Lambda in position with suspend function expected type:

simple case - val initializer.
This commit is contained in:
Dmitry Petrov
2016-12-14 16:00:13 +03:00
committed by Stanislav Erokhin
parent 9dc458375a
commit bc069cd686
5 changed files with 90 additions and 5 deletions
@@ -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)
@@ -0,0 +1,23 @@
interface Foo {
val foo: suspend () -> Unit
}
interface Bar<T> {
val bar: T
}
class Test1 : Foo {
override val <!PROPERTY_TYPE_MISMATCH_ON_OVERRIDE!>foo<!> = {}
}
class Test2 : Foo {
override val foo: suspend () -> Unit = {}
}
class Test3 : Bar<suspend () -> Unit> {
override val <!PROPERTY_TYPE_MISMATCH_ON_OVERRIDE!>bar<!> = {}
}
class Test4 : Bar<suspend () -> Unit> {
override val bar: suspend () -> Unit = {}
}
@@ -0,0 +1,47 @@
package
public interface Bar</*0*/ T> {
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<suspend () -> 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<suspend () -> 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
}
@@ -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 = {}
@@ -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