KT-51284 Fix SAM conversion for methods with context receivers

This commit is contained in:
Pavel Mikhailovskii
2022-12-07 09:01:21 +00:00
committed by Space Team
parent cc9beb466e
commit 4676072137
5 changed files with 42 additions and 4 deletions
@@ -17456,6 +17456,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/iteratorOperator.kt"); runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/iteratorOperator.kt");
} }
@Test
@TestMetadata("kt51284.kt")
public void testKt51284() throws Exception {
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/kt51284.kt");
}
@Test @Test
@TestMetadata("kt51863.kt") @TestMetadata("kt51863.kt")
public void testKt51863() throws Exception { public void testKt51863() throws Exception {
@@ -387,12 +387,15 @@ private fun FirSimpleFunction.getFunctionTypeForAbstractMethod(): ConeLookupTagB
val parameterTypes = valueParameters.map { val parameterTypes = valueParameters.map {
it.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: ConeErrorType(ConeIntermediateDiagnostic("No type for parameter $it")) it.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: ConeErrorType(ConeIntermediateDiagnostic("No type for parameter $it"))
} }
val contextReceiversTypes = contextReceivers.map {
it.typeRef.coneTypeSafe<ConeKotlinType>() ?: ConeErrorType(ConeIntermediateDiagnostic("No type for context receiver $it"))
}
return createFunctionalType( return createFunctionalType(
parameterTypes, parameterTypes,
receiverType = receiverParameter?.typeRef?.coneType, receiverType = receiverParameter?.typeRef?.coneType,
rawReturnType = returnTypeRef.coneType, rawReturnType = returnTypeRef.coneType,
isSuspend = this.isSuspend isSuspend = this.isSuspend,
contextReceivers = contextReceiversTypes
) )
} }
@@ -0,0 +1,23 @@
// !LANGUAGE: +ContextReceivers
// TARGET_BACKEND: JVM_IR
class Context
fun interface SAM {
context(Context)
fun foo(x: Int): Int
}
fun box(): String {
val sam1 = SAM { x -> x + 1 }
val sam2 = SAM { 2 }
val sam3 = SAM { it + 1 }
with(Context()) {
sam1.foo(0)
sam2.foo(0)
sam3.foo(0)
}
return "OK"
}
@@ -17456,6 +17456,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/iteratorOperator.kt"); runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/iteratorOperator.kt");
} }
@Test
@TestMetadata("kt51284.kt")
public void testKt51284() throws Exception {
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/kt51284.kt");
}
@Test @Test
@TestMetadata("kt51863.kt") @TestMetadata("kt51863.kt")
public void testKt51863() throws Exception { public void testKt51863() throws Exception {
@@ -77,14 +77,14 @@ fun getFunctionTypeForAbstractMethod(
val parameterNames = ArrayList<Name>(valueParameters.size) val parameterNames = ArrayList<Name>(valueParameters.size)
val contextReceiversTypes = function.contextReceiverParameters.map { it.type } val contextReceiversTypes = function.contextReceiverParameters.map { it.type }
var startIndex = contextReceiversTypes.size var startIndex = 0
var receiverType: KotlinType? = null var receiverType: KotlinType? = null
val extensionReceiver = function.extensionReceiverParameter val extensionReceiver = function.extensionReceiverParameter
if (extensionReceiver != null) { if (extensionReceiver != null) {
receiverType = extensionReceiver.type receiverType = extensionReceiver.type
} else if (shouldConvertFirstParameterToDescriptor && function.valueParameters.isNotEmpty()) { } else if (shouldConvertFirstParameterToDescriptor && function.valueParameters.isNotEmpty()) {
receiverType = valueParameters[0].type receiverType = valueParameters[0].type
startIndex += 1 startIndex = 1
} }
for (i in startIndex until valueParameters.size) { for (i in startIndex until valueParameters.size) {