From 14c2690447733ccae333081d46d160ee726cdead Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Mon, 25 May 2015 14:24:35 +0300 Subject: [PATCH] Distinguish between no declared arguments and an empty argument list in a function literal If there are no arguments, any number of them might be expected --- .../kotlin/resolve/calls/ArgumentTypeResolver.java | 4 ++-- .../tests/overload/EmptyArgumentListInLambda.kt | 8 ++++++++ .../tests/overload/EmptyArgumentListInLambda.txt | 5 +++++ .../kotlin/checkers/JetDiagnosticsTestGenerated.java | 6 ++++++ .../resolve/calls/inference/ConstraintSystemImpl.kt | 5 ++--- .../src/org/jetbrains/kotlin/types/ErrorUtils.java | 12 +++++++++--- 6 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/overload/EmptyArgumentListInLambda.kt create mode 100644 compiler/testData/diagnostics/tests/overload/EmptyArgumentListInLambda.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java index b3b81a31614..d5c004e802b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java @@ -233,7 +233,7 @@ public class ArgumentTypeResolver { boolean isFunctionLiteral = function instanceof JetFunctionLiteral; if (function.getValueParameterList() == null && isFunctionLiteral) { return expectedTypeIsUnknown - ? ErrorUtils.createFunctionPlaceholderType(Collections.emptyList()) + ? ErrorUtils.createFunctionPlaceholderType(Collections.emptyList(), /* hasDeclaredArguments = */ false) : builtIns.getFunctionType(Annotations.EMPTY, null, Collections.emptyList(), DONT_CARE); } List valueParameters = function.getValueParameters(); @@ -248,7 +248,7 @@ public class ArgumentTypeResolver { JetType receiverType = resolveTypeRefWithDefault(function.getReceiverTypeReference(), scope, temporaryTrace, null); return expectedTypeIsUnknown && isFunctionLiteral - ? ErrorUtils.createFunctionPlaceholderType(parameterTypes) + ? ErrorUtils.createFunctionPlaceholderType(parameterTypes, /* hasDeclaredArguments = */ true) : builtIns.getFunctionType(Annotations.EMPTY, receiverType, parameterTypes, returnType); } diff --git a/compiler/testData/diagnostics/tests/overload/EmptyArgumentListInLambda.kt b/compiler/testData/diagnostics/tests/overload/EmptyArgumentListInLambda.kt new file mode 100644 index 00000000000..06de4fb5a0e --- /dev/null +++ b/compiler/testData/diagnostics/tests/overload/EmptyArgumentListInLambda.kt @@ -0,0 +1,8 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun foo(g: () -> Int) {} +fun foo(f: (Int) -> Int) {} + +fun test() { + foo { -> 42 } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/overload/EmptyArgumentListInLambda.txt b/compiler/testData/diagnostics/tests/overload/EmptyArgumentListInLambda.txt new file mode 100644 index 00000000000..247d7450c08 --- /dev/null +++ b/compiler/testData/diagnostics/tests/overload/EmptyArgumentListInLambda.txt @@ -0,0 +1,5 @@ +package + +internal fun foo(/*0*/ g: () -> kotlin.Int): kotlin.Unit +internal fun foo(/*0*/ f: (kotlin.Int) -> kotlin.Int): kotlin.Unit +internal fun test(): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 3a5e662070d..914d580e4d8 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -9012,6 +9012,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("EmptyArgumentListInLambda.kt") + public void testEmptyArgumentListInLambda() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/overload/EmptyArgumentListInLambda.kt"); + doTest(fileName); + } + @TestMetadata("ExtFunDifferentReceiver.kt") public void testExtFunDifferentReceiver() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/overload/ExtFunDifferentReceiver.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt index 10d6697dac7..43c9479c5a8 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt @@ -423,10 +423,9 @@ fun createCorrespondingFunctionTypeForFunctionPlaceholder( ): JetType { assert(ErrorUtils.isFunctionPlaceholder(functionPlaceholder)) { "Function placeholder type expected: $functionPlaceholder" } val functionPlaceholderTypeConstructor = functionPlaceholder.getConstructor() as FunctionPlaceholderTypeConstructor - val declaredArgumentTypes = functionPlaceholderTypeConstructor.getArgumentTypes() val isExtension = KotlinBuiltIns.isExtensionFunctionType(expectedType) - val newArgumentTypes = if (declaredArgumentTypes.isEmpty()) { + val newArgumentTypes = if (!functionPlaceholderTypeConstructor.hasDeclaredArguments()) { val typeParamSize = expectedType.getConstructor().getParameters().size() // the first parameter is receiver (if present), the last one is return type, // the remaining are function arguments @@ -436,7 +435,7 @@ fun createCorrespondingFunctionTypeForFunctionPlaceholder( result } else { - declaredArgumentTypes + functionPlaceholderTypeConstructor.getArgumentTypes() } val receiverType = if (isExtension) DONT_CARE else null return KotlinBuiltIns.getInstance().getFunctionType(Annotations.EMPTY, receiverType, newArgumentTypes, DONT_CARE) diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java index 328d2c1ad54..bb40faf2d6f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java @@ -546,19 +546,21 @@ public class ErrorUtils { } @NotNull - public static JetType createFunctionPlaceholderType(@NotNull List argumentTypes) { + public static JetType createFunctionPlaceholderType(@NotNull List argumentTypes, boolean hasDeclaredArguments) { return new ErrorTypeImpl( - new FunctionPlaceholderTypeConstructor(argumentTypes), + new FunctionPlaceholderTypeConstructor(argumentTypes, hasDeclaredArguments), createErrorScope("Scope for function placeholder type")); } public static class FunctionPlaceholderTypeConstructor implements TypeConstructor { private final TypeConstructor errorTypeConstructor; private final List argumentTypes; + private final boolean hasDeclaredArguments; - private FunctionPlaceholderTypeConstructor(@NotNull List argumentTypes) { + private FunctionPlaceholderTypeConstructor(@NotNull List argumentTypes, boolean hasDeclaredArguments) { errorTypeConstructor = createErrorTypeConstructorWithCustomDebugName("PLACEHOLDER_FUNCTION_TYPE" + argumentTypes); this.argumentTypes = argumentTypes; + this.hasDeclaredArguments = hasDeclaredArguments; } @NotNull @@ -566,6 +568,10 @@ public class ErrorUtils { return argumentTypes; } + public boolean hasDeclaredArguments() { + return hasDeclaredArguments; + } + @NotNull @Override public List getParameters() {