[IR] Fix for https://youtrack.jetbrains.com/issue/KT-44799
This commit is contained in:
committed by
Vasily Levchenko
parent
f6f050ff68
commit
ab36e919bc
+43
-57
@@ -263,65 +263,51 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
|
|||||||
private val kSuspendFunctionImplConstructorSymbol = kSuspendFunctionImplSymbol.constructors.single()
|
private val kSuspendFunctionImplConstructorSymbol = kSuspendFunctionImplSymbol.constructors.single()
|
||||||
|
|
||||||
fun build(): BuiltFunctionReference {
|
fun build(): BuiltFunctionReference {
|
||||||
val numberOfParameters = unboundFunctionParameters.size
|
val superClass = when {
|
||||||
val functionParameterTypes = unboundFunctionParameters.map { it.type }
|
isKSuspendFunction -> kSuspendFunctionImplSymbol.typeWith(referencedFunction.returnType)
|
||||||
val superTypes = mutableListOf<IrType>()
|
isLambda -> irBuiltIns.anyType
|
||||||
val functionClass: IrClass
|
else -> kFunctionImplSymbol.typeWith(referencedFunction.returnType)
|
||||||
val suspendFunctionClass: IrClass?
|
|
||||||
if (isKSuspendFunction) {
|
|
||||||
superTypes += kSuspendFunctionImplSymbol.typeWith(referencedFunction.returnType)
|
|
||||||
functionClass = symbols.functionN(numberOfParameters + 1).owner
|
|
||||||
val continuationType = continuationClassSymbol.typeWith(referencedFunction.returnType)
|
|
||||||
superTypes += functionClass.typeWith(functionParameterTypes + continuationType + irBuiltIns.anyNType)
|
|
||||||
suspendFunctionClass = symbols.kSuspendFunctionN(numberOfParameters).owner
|
|
||||||
superTypes += suspendFunctionClass.typeWith(functionParameterTypes + referencedFunction.returnType)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
superTypes += if (isLambda)
|
|
||||||
irBuiltIns.anyType
|
|
||||||
else
|
|
||||||
kFunctionImplSymbol.typeWith(referencedFunction.returnType)
|
|
||||||
functionClass = (if (isKFunction) symbols.kFunctionN(numberOfParameters) else symbols.functionN(numberOfParameters)).owner
|
|
||||||
superTypes += functionClass.typeWith(functionParameterTypes + referencedFunction.returnType)
|
|
||||||
val lastParameterType = unboundFunctionParameters.lastOrNull()?.type
|
|
||||||
if (lastParameterType?.classifierOrNull != continuationClassSymbol)
|
|
||||||
suspendFunctionClass = null
|
|
||||||
else {
|
|
||||||
lastParameterType as IrSimpleType
|
|
||||||
// If the last parameter is Continuation<> inherit from SuspendFunction.
|
|
||||||
suspendFunctionClass = symbols.suspendFunctionN(numberOfParameters - 1).owner
|
|
||||||
val suspendFunctionClassTypeParameters = functionParameterTypes.dropLast(1) +
|
|
||||||
(lastParameterType.arguments.single().typeOrNull ?: irBuiltIns.anyNType)
|
|
||||||
superTypes += suspendFunctionClass.symbol.typeWith(suspendFunctionClassTypeParameters)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
val superTypes = mutableListOf(superClass)
|
||||||
|
if (samSuperType != null) {
|
||||||
|
superTypes += samSuperType
|
||||||
|
|
||||||
val constructor = buildConstructor()
|
val sam = samSuperClass!!.functions.single { it.owner.modality == Modality.ABSTRACT }
|
||||||
val functionInvoke = if (isKSuspendFunction)
|
buildInvokeMethod(sam.owner)
|
||||||
null
|
} else {
|
||||||
else
|
val numberOfParameters = unboundFunctionParameters.size
|
||||||
buildInvokeMethod(functionClass.getInvokeFunction())
|
val functionParameterTypes = unboundFunctionParameters.map { it.type }
|
||||||
val suspendFunctionInvoke = if (suspendFunctionClass == null)
|
val functionClass: IrClass
|
||||||
null
|
val suspendFunctionClass: IrClass?
|
||||||
else {
|
if (isKSuspendFunction) {
|
||||||
buildInvokeMethod(suspendFunctionClass.getInvokeFunction()).also {
|
functionClass = symbols.functionN(numberOfParameters + 1).owner
|
||||||
if (isKSuspendFunction)
|
val continuationType = continuationClassSymbol.typeWith(referencedFunction.returnType)
|
||||||
it.overriddenSymbols += functionClass.getInvokeFunction().symbol
|
superTypes += functionClass.typeWith(functionParameterTypes + continuationType + irBuiltIns.anyNType)
|
||||||
|
suspendFunctionClass = symbols.kSuspendFunctionN(numberOfParameters).owner
|
||||||
|
superTypes += suspendFunctionClass.typeWith(functionParameterTypes + referencedFunction.returnType)
|
||||||
|
} else {
|
||||||
|
functionClass = (if (isKFunction) symbols.kFunctionN(numberOfParameters) else symbols.functionN(numberOfParameters)).owner
|
||||||
|
superTypes += functionClass.typeWith(functionParameterTypes + referencedFunction.returnType)
|
||||||
|
val lastParameterType = unboundFunctionParameters.lastOrNull()?.type
|
||||||
|
if (lastParameterType?.classifierOrNull != continuationClassSymbol)
|
||||||
|
suspendFunctionClass = null
|
||||||
|
else {
|
||||||
|
lastParameterType as IrSimpleType
|
||||||
|
// If the last parameter is Continuation<> inherit from SuspendFunction.
|
||||||
|
suspendFunctionClass = symbols.suspendFunctionN(numberOfParameters - 1).owner
|
||||||
|
val suspendFunctionClassTypeParameters = functionParameterTypes.dropLast(1) +
|
||||||
|
(lastParameterType.arguments.single().typeOrNull ?: irBuiltIns.anyNType)
|
||||||
|
superTypes += suspendFunctionClass.symbol.typeWith(suspendFunctionClassTypeParameters)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
samSuperType?.let { superTypes += it }
|
if (!isKSuspendFunction)
|
||||||
val sam = samSuperClass?.functions?.single { it.owner.modality == Modality.ABSTRACT }
|
buildInvokeMethod(functionClass.getInvokeFunction())
|
||||||
if (sam != null) {
|
if (suspendFunctionClass != null) {
|
||||||
if (sam.owner.extensionReceiverParameter != null)
|
buildInvokeMethod(suspendFunctionClass.getInvokeFunction()).also {
|
||||||
buildInvokeMethod(sam.owner)
|
if (isKSuspendFunction)
|
||||||
else {
|
it.overriddenSymbols += functionClass.getInvokeFunction().symbol
|
||||||
// The signatures of SAM and [invoke] coincide - no need to build additional function.
|
}
|
||||||
val properInvoke = if (sam.isSuspend)
|
|
||||||
suspendFunctionInvoke
|
|
||||||
else
|
|
||||||
functionInvoke
|
|
||||||
if (properInvoke != null)
|
|
||||||
properInvoke.overriddenSymbols += sam
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,7 +315,7 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
|
|||||||
|
|
||||||
functionReferenceClass.addFakeOverrides(context.irBuiltIns)
|
functionReferenceClass.addFakeOverrides(context.irBuiltIns)
|
||||||
|
|
||||||
return BuiltFunctionReference(functionReferenceClass, constructor)
|
return BuiltFunctionReference(functionReferenceClass, buildConstructor())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildConstructor(): IrConstructor =
|
private fun buildConstructor(): IrConstructor =
|
||||||
|
|||||||
@@ -2864,6 +2864,10 @@ standaloneTest("lambda14") {
|
|||||||
flags = ['-tr']
|
flags = ['-tr']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task funInterface_implIsNotFunction(type: KonanLocalTest) {
|
||||||
|
source = "codegen/funInterface/implIsNotFunction.kt"
|
||||||
|
}
|
||||||
|
|
||||||
task objectExpression1(type: KonanLocalTest) {
|
task objectExpression1(type: KonanLocalTest) {
|
||||||
goldValue = "aabb\n"
|
goldValue = "aabb\n"
|
||||||
source = "codegen/objectExpression/expr1.kt"
|
source = "codegen/objectExpression/expr1.kt"
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package codegen.funInterface.implIsNotFunction
|
||||||
|
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
fun interface Foo {
|
||||||
|
fun invoke(): String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(f: Foo) = f is Function<*>
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun test() {
|
||||||
|
assertFalse(foo { "zzz" })
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user