Fix anonymous function literals handling in type checker
- [NI] Create type info directly if the expected type is functional. - Properly handle suspended function expected type.
This commit is contained in:
committed by
Mikhail Zarechenskiy
parent
6facdcb7ea
commit
26cc08be65
+23
-7
@@ -123,7 +123,17 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
||||
createTypeInfo(components.dataFlowAnalyzer.checkStatementType(function, context), context)
|
||||
}
|
||||
else {
|
||||
components.dataFlowAnalyzer.createCheckedTypeInfo(functionDescriptor.createFunctionType(), context, function)
|
||||
val expectedType = context.expectedType
|
||||
|
||||
val functionalTypeExpected = expectedType.isBuiltinFunctionalType()
|
||||
val suspendFunctionTypeExpected = expectedType.isSuspendFunctionType()
|
||||
|
||||
val resultType = functionDescriptor.createFunctionType(suspendFunctionTypeExpected)
|
||||
|
||||
if (functionalTypeExpected)
|
||||
createTypeInfo(resultType, context)
|
||||
else
|
||||
components.dataFlowAnalyzer.createCheckedTypeInfo(resultType, context, function)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,8 +154,8 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
||||
if (!expression.functionLiteral.hasBody()) return null
|
||||
|
||||
val expectedType = context.expectedType
|
||||
val functionTypeExpected = !noExpectedType(expectedType) && expectedType.isBuiltinFunctionalType
|
||||
val suspendFunctionTypeExpected = !noExpectedType(expectedType) && expectedType.isSuspendFunctionType
|
||||
val functionTypeExpected = expectedType.isBuiltinFunctionalType()
|
||||
val suspendFunctionTypeExpected = expectedType.isSuspendFunctionType()
|
||||
|
||||
val functionDescriptor = createFunctionLiteralDescriptor(expression, context)
|
||||
expression.valueParameters.forEach {
|
||||
@@ -174,10 +184,10 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
||||
): AnonymousFunctionDescriptor {
|
||||
val functionLiteral = expression.functionLiteral
|
||||
val functionDescriptor = AnonymousFunctionDescriptor(
|
||||
context.scope.ownerDescriptor,
|
||||
components.annotationResolver.resolveAnnotationsWithArguments(context.scope, expression.getAnnotationEntries(), context.trace),
|
||||
CallableMemberDescriptor.Kind.DECLARATION, functionLiteral.toSourceElement(),
|
||||
!noExpectedType(context.expectedType) && context.expectedType.isSuspendFunctionType
|
||||
context.scope.ownerDescriptor,
|
||||
components.annotationResolver.resolveAnnotationsWithArguments(context.scope, expression.getAnnotationEntries(), context.trace),
|
||||
CallableMemberDescriptor.Kind.DECLARATION, functionLiteral.toSourceElement(),
|
||||
context.expectedType.isSuspendFunctionType()
|
||||
)
|
||||
components.functionDescriptorResolver.
|
||||
initializeFunctionDescriptorAndExplicitReturnType(context.scope.ownerDescriptor, context.scope, functionLiteral,
|
||||
@@ -189,6 +199,12 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
||||
return functionDescriptor
|
||||
}
|
||||
|
||||
private fun KotlinType.isBuiltinFunctionalType() =
|
||||
!noExpectedType(this) && isBuiltinFunctionalType
|
||||
|
||||
private fun KotlinType.isSuspendFunctionType() =
|
||||
!noExpectedType(this) && isSuspendFunctionType
|
||||
|
||||
private fun computeReturnType(
|
||||
expression: KtLambdaExpression,
|
||||
context: ExpressionTypingContext,
|
||||
|
||||
+5
@@ -4,3 +4,8 @@ val test1: suspend () -> Unit = {}
|
||||
val test2: suspend Any.() -> Unit = {}
|
||||
val test3: suspend Any.(Int) -> Int = { k: Int -> k + 1 }
|
||||
val test4: SuspendFn = {}
|
||||
|
||||
val test1f: suspend () -> Unit = fun () {}
|
||||
val test2f: suspend Any.() -> Unit = fun Any.() {}
|
||||
val test3f: suspend Any.(Int) -> Int = fun (k: Int) = k + 1
|
||||
val test4f: SuspendFn = fun Any.() {}
|
||||
|
||||
+4
@@ -1,7 +1,11 @@
|
||||
package
|
||||
|
||||
public val test1: suspend () -> kotlin.Unit
|
||||
public val test1f: suspend () -> kotlin.Unit
|
||||
public val test2: suspend kotlin.Any.() -> kotlin.Unit
|
||||
public val test2f: suspend kotlin.Any.() -> kotlin.Unit
|
||||
public val test3: suspend kotlin.Any.(kotlin.Int) -> kotlin.Int
|
||||
public val test3f: suspend kotlin.Any.(kotlin.Int) -> kotlin.Int
|
||||
public val test4: SuspendFn /* = suspend () -> kotlin.Unit */
|
||||
public val test4f: SuspendFn /* = suspend () -> kotlin.Unit */
|
||||
public typealias SuspendFn = suspend () -> kotlin.Unit
|
||||
|
||||
Reference in New Issue
Block a user