From bc069cd6861ba79b214c8b16a572918eb4ffb53e Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 14 Dec 2016 16:00:13 +0300 Subject: [PATCH] Lambda in position with suspend function expected type: simple case - val initializer. --- .../expressions/FunctionsTypingVisitor.kt | 12 +++-- .../lambdaInOverriddenValInitializer.kt | 23 +++++++++ .../lambdaInOverriddenValInitializer.txt | 47 +++++++++++++++++++ .../lambdaInValInitializer.kt | 6 +++ .../lambdaInValInitializer.txt | 7 +++ 5 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInOverriddenValInitializer.kt create mode 100644 compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInOverriddenValInitializer.txt create mode 100644 compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInValInitializer.kt create mode 100644 compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInValInitializer.txt 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 b323ff48333..f1c43d3097f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt @@ -20,7 +20,7 @@ import com.google.common.collect.Lists import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.createFunctionType import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType -import org.jetbrains.kotlin.builtins.isFunctionType +import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations @@ -126,14 +126,15 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre } } - private fun SimpleFunctionDescriptor.createFunctionType(): KotlinType? { + private fun SimpleFunctionDescriptor.createFunctionType(suspendFunction: Boolean = false): KotlinType? { return createFunctionType( components.builtIns, Annotations.EMPTY, extensionReceiverParameter?.type, valueParameters.map { it.type }, null, - returnType ?: return null + returnType ?: return null, + suspendFunction = suspendFunction ) } @@ -141,7 +142,8 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre if (!expression.functionLiteral.hasBody()) return null val expectedType = context.expectedType - val functionTypeExpected = !noExpectedType(expectedType) && expectedType.isFunctionType + val functionTypeExpected = !noExpectedType(expectedType) && expectedType.isBuiltinFunctionalType + val suspendFunctionTypeExpected = !noExpectedType(expectedType) && expectedType.isSuspendFunctionType val functionDescriptor = createFunctionLiteralDescriptor(expression, context) expression.valueParameters.forEach { @@ -151,7 +153,7 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre val safeReturnType = computeReturnType(expression, context, functionDescriptor, functionTypeExpected) functionDescriptor.setReturnType(safeReturnType) - val resultType = functionDescriptor.createFunctionType()!! + val resultType = functionDescriptor.createFunctionType(suspendFunctionTypeExpected)!! if (functionTypeExpected) { // all checks were done before return createTypeInfo(resultType, context) diff --git a/compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInOverriddenValInitializer.kt b/compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInOverriddenValInitializer.kt new file mode 100644 index 00000000000..1cdd795aa1c --- /dev/null +++ b/compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInOverriddenValInitializer.kt @@ -0,0 +1,23 @@ +interface Foo { + val foo: suspend () -> Unit +} + +interface Bar { + val bar: T +} + +class Test1 : Foo { + override val foo = {} +} + +class Test2 : Foo { + override val foo: suspend () -> Unit = {} +} + +class Test3 : Bar Unit> { + override val bar = {} +} + +class Test4 : Bar Unit> { + override val bar: suspend () -> Unit = {} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInOverriddenValInitializer.txt b/compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInOverriddenValInitializer.txt new file mode 100644 index 00000000000..d680c477956 --- /dev/null +++ b/compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInOverriddenValInitializer.txt @@ -0,0 +1,47 @@ +package + +public interface Bar { + public abstract val bar: T + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Foo { + public abstract val foo: suspend () -> kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Test1 : Foo { + public constructor Test1() + public open override /*1*/ val foo: () -> kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Test2 : Foo { + public constructor Test2() + public open override /*1*/ val foo: suspend () -> kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Test3 : Bar kotlin.Unit> { + public constructor Test3() + public open override /*1*/ val bar: () -> kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Test4 : Bar kotlin.Unit> { + public constructor Test4() + public open override /*1*/ val bar: suspend () -> kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInValInitializer.kt b/compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInValInitializer.kt new file mode 100644 index 00000000000..e892e54f7cb --- /dev/null +++ b/compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInValInitializer.kt @@ -0,0 +1,6 @@ +typealias SuspendFn = suspend () -> Unit + +val test1: suspend () -> Unit = {} +val test2: suspend Any.() -> Unit = {} +val test3: suspend Any.(Int) -> Int = { k: Int -> k + 1 } +val test4: SuspendFn = {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInValInitializer.txt b/compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInValInitializer.txt new file mode 100644 index 00000000000..b16b1d8303d --- /dev/null +++ b/compiler/testData/diagnostics/tests/coroutines/suspendFunctionType/lambdaInValInitializer.txt @@ -0,0 +1,7 @@ +package + +public val test1: suspend () -> kotlin.Unit +public val test2: suspend kotlin.Any.() -> kotlin.Unit +public val test3: suspend kotlin.Any.(kotlin.Int) -> kotlin.Int +public val test4: SuspendFn /* = suspend () -> kotlin.Unit */ +public typealias SuspendFn = suspend () -> kotlin.Unit