From 5a3367e09cb8a4abb2768cec2c401a86318dff07 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Fri, 24 Jul 2020 15:19:28 -0700 Subject: [PATCH] FIR: initial support of suspend conversion for function reference --- .../generators/CallAndReferenceGenerator.kt | 187 ++++++++++++++++-- .../fir/resolve/calls/ResolutionStages.kt | 10 +- .../adaptedWithCoercionToUnit.kt | 1 - .../adaptedWithDefaultArguments.kt | 1 - .../suspendConversion/crossInline.kt | 1 - .../inlineAdaptedWithCoercionToUnit.kt | 1 - .../inlineAdaptedWithDefaultArguments.kt | 1 - .../suspendConversion/inlineSimple.kt | 1 - .../suspendConversion/inlineWithParameters.kt | 1 - .../suspendConversion/simple.kt | 1 - .../suspendConversion/withParameters.kt | 1 - ...spendConversionForCallableReference.fir.kt | 6 +- .../suspendConversionCompatibility.fir.kt | 2 +- ...nversionCompatibilityInDisabledMode.fir.kt | 4 +- .../suspendConversionDisabled.fir.kt | 2 +- .../suspendConversionWithFunInterfaces.fir.kt | 21 -- .../suspendConversionWithFunInterfaces.kt | 1 + ...ndConversionWithReferenceAdaptation.fir.kt | 6 +- .../chainedFunSuspendUnitConversion.fir.kt | 2 +- .../chainedUnitSuspendConversion.fir.kt | 2 +- .../suspendConversion.fir.txt | 46 +++-- 21 files changed, 230 insertions(+), 68 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.fir.kt diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index 7d35e935a70..ae35978c91d 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -5,6 +5,9 @@ package org.jetbrains.kotlin.fir.backend.generators +import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.* @@ -18,22 +21,28 @@ import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.calls.isFunctional import org.jetbrains.kotlin.fir.resolve.getCorrespondingConstructorReferenceOrNull import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType +import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrDeclaration -import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.declarations.IrProperty +import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor +import org.jetbrains.kotlin.ir.descriptors.WrappedValueParameterDescriptor import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.types.toArrayOrPrimitiveArrayType -import org.jetbrains.kotlin.ir.util.parentClassOrNull +import org.jetbrains.kotlin.ir.types.typeOrNull +import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtPropertyDelegate import org.jetbrains.kotlin.psi2ir.generators.hasNoSideEffects @@ -87,12 +96,18 @@ class CallAndReferenceGenerator( } is IrFunctionSymbol -> { val function = symbol.owner - IrFunctionReferenceImpl( - startOffset, endOffset, type, symbol, - typeArgumentsCount = function.typeParameters.size, - valueArgumentsCount = function.valueParameters.size, - reflectionTarget = symbol - ) + // TODO: should refer to LanguageVersionSettings.SuspendConversion + if (requiresSuspendConversion(type, function)) { + val adaptedType = callableReferenceAccess.typeRef.coneType.kFunctionTypeToFunctionType() + generateAdaptedCallableReference(callableReferenceAccess, symbol, adaptedType) + } else { + IrFunctionReferenceImpl( + startOffset, endOffset, type, symbol, + typeArgumentsCount = function.typeParameters.size, + valueArgumentsCount = function.valueParameters.size, + reflectionTarget = symbol + ) + } } else -> { IrErrorCallExpressionImpl( @@ -103,6 +118,156 @@ class CallAndReferenceGenerator( }.applyTypeArguments(callableReferenceAccess).applyReceivers(callableReferenceAccess, explicitReceiverExpression) } + private fun requiresSuspendConversion(type: IrType, function: IrFunction): Boolean = + type.isKSuspendFunction() && !function.isSuspend + + private fun ConeKotlinType.kFunctionTypeToFunctionType(): IrSimpleType { + val kind = + if (isSuspendFunctionType(session)) FunctionClassDescriptor.Kind.SuspendFunction + else FunctionClassDescriptor.Kind.Function + val functionalTypeId = ClassId(kind.packageFqName, kind.numberedClassName(typeArguments.size - 1)) + val coneType = ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(functionalTypeId), typeArguments, isNullable = false) + return coneType.toIrType() as IrSimpleType + } + + private fun generateAdaptedCallableReference( + callableReferenceAccess: FirCallableReferenceAccess, + adapteeSymbol: IrFunctionSymbol, + type: IrSimpleType + ): IrExpression { + val firAdaptee = callableReferenceAccess.toResolvedCallableReference()?.resolvedSymbol?.fir as? FirSimpleFunction + val adaptee = adapteeSymbol.owner + // TODO: handle bound receiver, e.g., c::foo + return callableReferenceAccess.convertWithOffsets { startOffset, endOffset -> + val irAdapterFunction = createAdapterFunctionForSuspendConversion(startOffset, endOffset, firAdaptee!!, adaptee, type) + val irCall = createAdapteeCall(callableReferenceAccess, adapteeSymbol, irAdapterFunction) + irAdapterFunction.body = irFactory.createBlockBody(startOffset, endOffset) { + if (firAdaptee.returnTypeRef.isUnit) { + statements.add(irCall) + } else { + statements.add(IrReturnImpl(startOffset, endOffset, irBuiltIns.nothingType, irAdapterFunction.symbol, irCall)) + } + } + + IrFunctionExpressionImpl(startOffset, endOffset, type, irAdapterFunction, IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE) + } + } + + private fun createAdapterFunctionForSuspendConversion( + startOffset: Int, + endOffset: Int, + firAdaptee: FirSimpleFunction, + adaptee: IrFunction, + type: IrSimpleType, + ): IrSimpleFunction { + val returnType = type.arguments.last().typeOrNull!! + val parameterTypes = type.arguments.dropLast(1).map { it.typeOrNull!! } + val adapterFunctionDescriptor = WrappedSimpleFunctionDescriptor() + return symbolTable.declareSimpleFunction(adapterFunctionDescriptor) { irAdapterSymbol -> + irFactory.createFunction( + startOffset, endOffset, + IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE, + irAdapterSymbol, + adaptee.name, + Visibilities.LOCAL, + Modality.FINAL, + returnType, + isInline = firAdaptee.isInline, + isExternal = firAdaptee.isExternal, + isTailrec = firAdaptee.isTailRec, + isSuspend = true, + isOperator = firAdaptee.isOperator, + isInfix = firAdaptee.isInfix, + isExpect = firAdaptee.isExpect, + isFakeOverride = false + ).also { irAdapterFunction -> + adapterFunctionDescriptor.bind(irAdapterFunction) + irAdapterFunction.metadata = FirMetadataSource.Function(firAdaptee) + symbolTable.enterScope(irAdapterFunction) + irAdapterFunction.valueParameters += parameterTypes.mapIndexed { index, parameterType -> + createAdapterParameter(irAdapterFunction, Name.identifier("p$index"), index, parameterType) + } + symbolTable.leaveScope(irAdapterFunction) + irAdapterFunction.parent = conversionScope.parent()!! + } + } + } + + private fun createAdapterParameter( + adapterFunction: IrFunction, + name: Name, + index: Int, + type: IrType + ): IrValueParameter { + val startOffset = adapterFunction.startOffset + val endOffset = adapterFunction.endOffset + val descriptor = WrappedValueParameterDescriptor() + return symbolTable.declareValueParameter( + startOffset, endOffset, IrDeclarationOrigin.ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE, descriptor, type + ) { irAdapterParameterSymbol -> + irFactory.createValueParameter( + startOffset, endOffset, + IrDeclarationOrigin.ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE, + irAdapterParameterSymbol, + name, + index, + type, + varargElementType = null, + isCrossinline = false, + isNoinline = false + ).also { irAdapterValueParameter -> + descriptor.bind(irAdapterValueParameter) + irAdapterValueParameter.parent = adapterFunction + } + } + } + + private fun createAdapteeCall( + callableReferenceAccess: FirCallableReferenceAccess, + adapteeSymbol: IrFunctionSymbol, + adapterFunction: IrFunction + ): IrExpression { + val adapteeFunction = adapteeSymbol.owner + val startOffset = adapteeFunction.startOffset + val endOffset = adapteeFunction.endOffset + val type = adapteeFunction.returnType + val irCall = + if (adapteeSymbol is IrConstructorSymbol) { + IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, type, adapteeSymbol) + } else { + IrCallImpl( + startOffset, + endOffset, + type, + adapteeSymbol, + callableReferenceAccess.typeArguments.size, + adapteeFunction.valueParameters.size, + origin = null, + superQualifierSymbol = null + ) + } + + // TODO: handle non-transient, bound dispatch/extension receiver + + adapteeFunction.valueParameters.mapIndexed { index, valueParameter -> + when { + valueParameter.hasDefaultValue() -> { + irCall.putValueArgument(index, null) + } + valueParameter.isVararg -> { + // TODO: handle vararg and spread + irCall.putValueArgument(index, null) + } + else -> { + val irValueArgument = adapterFunction.valueParameters[index] + irCall.putValueArgument(index, IrGetValueImpl(startOffset, endOffset, irValueArgument.type, irValueArgument.symbol)) + } + } + } + + return irCall.applyTypeArguments(callableReferenceAccess) + } + private fun FirQualifiedAccess.tryConvertToSamConstructorCall(type: IrType): IrTypeOperatorCall? { val calleeReference = calleeReference as? FirResolvedNamedReference ?: return null val fir = calleeReference.resolvedSymbol.fir diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index f8759fc237b..be69797c4ad 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -220,12 +220,18 @@ internal object CheckCallableReferenceExpectedType : CheckerStage() { } val returnTypeRef = candidate.bodyResolveComponents.returnTypeCalculator.tryCalculateReturnType(fir) - + // If the expected type is a suspend function type and the current argument of interest is a function reference, we need to do + // "suspend conversion." Here, during resolution, we bypass constraint system by making resulting type be KSuspendFunction. + // Then, during conversion, we need to create an adapter function and replace the function reference created here with an adapted + // callable reference. + // TODO: should refer to LanguageVersionSettings.SuspendConversion + val requireSuspendConversion = expectedType?.isSuspendFunctionType(callInfo.session) == true + // TODO: handle callable reference with vararg val resultingType: ConeKotlinType = when (fir) { is FirFunction -> callInfo.session.createKFunctionType( fir, resultingReceiverType, returnTypeRef, expectedParameterNumberWithReceiver = expectedType?.let { it.typeArguments.size - 1 }, - isSuspend = (fir as? FirSimpleFunction)?.isSuspend == true, + isSuspend = (fir as? FirSimpleFunction)?.isSuspend == true || requireSuspendConversion, expectedReturnType = extractInputOutputTypesFromCallableReferenceExpectedType(expectedType, callInfo.session)?.outputType ) is FirVariable<*> -> createKPropertyType(fir, resultingReceiverType, returnTypeRef) diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/adaptedWithCoercionToUnit.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/adaptedWithCoercionToUnit.kt index e97a448df96..e63135228f9 100644 --- a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/adaptedWithCoercionToUnit.kt +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/adaptedWithCoercionToUnit.kt @@ -1,7 +1,6 @@ // !LANGUAGE: +SuspendConversion // WITH_RUNTIME // WITH_COROUTINES -// IGNORE_BACKEND_FIR: JVM_IR import helpers.* import kotlin.coroutines.* diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/adaptedWithDefaultArguments.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/adaptedWithDefaultArguments.kt index 7891bfa5eea..5941bff2a27 100644 --- a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/adaptedWithDefaultArguments.kt +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/adaptedWithDefaultArguments.kt @@ -1,7 +1,6 @@ // !LANGUAGE: +SuspendConversion // WITH_RUNTIME // WITH_COROUTINES -// IGNORE_BACKEND_FIR: JVM_IR import helpers.* import kotlin.coroutines.* diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/crossInline.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/crossInline.kt index ef87d44e6f4..c904caebf91 100644 --- a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/crossInline.kt +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/crossInline.kt @@ -1,7 +1,6 @@ // !LANGUAGE: +SuspendConversion // WITH_RUNTIME // WITH_COROUTINES -// IGNORE_BACKEND_FIR: JVM_IR import helpers.* import kotlin.coroutines.* diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineAdaptedWithCoercionToUnit.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineAdaptedWithCoercionToUnit.kt index 36a28fe67e2..f1f9ce38064 100644 --- a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineAdaptedWithCoercionToUnit.kt +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineAdaptedWithCoercionToUnit.kt @@ -1,7 +1,6 @@ // !LANGUAGE: +SuspendConversion // WITH_RUNTIME // WITH_COROUTINES -// IGNORE_BACKEND_FIR: JVM_IR import helpers.* import kotlin.coroutines.* diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineAdaptedWithDefaultArguments.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineAdaptedWithDefaultArguments.kt index 42682930938..24717ab4a8e 100644 --- a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineAdaptedWithDefaultArguments.kt +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineAdaptedWithDefaultArguments.kt @@ -1,7 +1,6 @@ // !LANGUAGE: +SuspendConversion // WITH_RUNTIME // WITH_COROUTINES -// IGNORE_BACKEND_FIR: JVM_IR import helpers.* import kotlin.coroutines.* diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineSimple.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineSimple.kt index 9fde734848a..292c2aa541a 100644 --- a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineSimple.kt +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineSimple.kt @@ -1,7 +1,6 @@ // !LANGUAGE: +SuspendConversion // WITH_RUNTIME // WITH_COROUTINES -// IGNORE_BACKEND_FIR: JVM_IR import helpers.* import kotlin.coroutines.* diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineWithParameters.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineWithParameters.kt index 799716a21ca..208458733f2 100644 --- a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineWithParameters.kt +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/inlineWithParameters.kt @@ -1,7 +1,6 @@ // !LANGUAGE: +SuspendConversion // WITH_RUNTIME // WITH_COROUTINES -// IGNORE_BACKEND_FIR: JVM_IR import helpers.* import kotlin.coroutines.* diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/simple.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/simple.kt index a8861a1da8d..ce54c5b3f73 100644 --- a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/simple.kt +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/simple.kt @@ -1,7 +1,6 @@ // !LANGUAGE: +SuspendConversion // WITH_RUNTIME // WITH_COROUTINES -// IGNORE_BACKEND_FIR: JVM_IR import helpers.* import kotlin.coroutines.* diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/withParameters.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/withParameters.kt index 17bb0549aec..602fd94c29f 100644 --- a/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/withParameters.kt +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/withParameters.kt @@ -1,7 +1,6 @@ // !LANGUAGE: +SuspendConversion // WITH_RUNTIME // WITH_COROUTINES -// IGNORE_BACKEND_FIR: JVM_IR import helpers.* import kotlin.coroutines.* diff --git a/compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionForCallableReference.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionForCallableReference.fir.kt index e939a1927b4..c04a53729ca 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionForCallableReference.fir.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionForCallableReference.fir.kt @@ -9,10 +9,10 @@ fun bar2(x: Int) {} fun bar2(s: String) {} fun test() { - foo1(::bar1) + foo1(::bar1) - foo2(42, ::bar2) - foo2("str", ::bar2) + foo2(42, ::bar2) + foo2("str", ::bar2) foo2(42, ::bar1) } diff --git a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionCompatibility.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionCompatibility.fir.kt index 0caf0fbc82f..17ba2c88e64 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionCompatibility.fir.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionCompatibility.fir.kt @@ -22,7 +22,7 @@ object Test2 { fun test() { val result = foo(::bar) - result + result } } } diff --git a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionCompatibilityInDisabledMode.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionCompatibilityInDisabledMode.fir.kt index fd796932e93..12ca5a79983 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionCompatibilityInDisabledMode.fir.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionCompatibilityInDisabledMode.fir.kt @@ -11,7 +11,7 @@ object Test1 { fun test() { val result = foo(::bar) - result + result } } } @@ -29,7 +29,7 @@ object Test2 { fun test() { val result = foo(::bar) - result + result } } } diff --git a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.fir.kt index 3ba40854cad..a507eae99b3 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.fir.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.fir.kt @@ -20,7 +20,7 @@ fun test( foo2(f2) foo3(f3) - foo1(::bar) + foo1(::bar) foo1(f2) foo1(f3) diff --git a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.fir.kt deleted file mode 100644 index c2b725e8e42..00000000000 --- a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.fir.kt +++ /dev/null @@ -1,21 +0,0 @@ -// !LANGUAGE: +SuspendConversion -// !DIAGNOSTICS: -UNUSED_PARAMETER - -fun interface SuspendRunnable { - suspend fun invoke() -} - -fun foo1(s: SuspendRunnable) {} -fun bar1() {} - -fun bar2(s: String = ""): Int = 0 - -fun bar3() {} -suspend fun bar3(s: String = ""): Int = 0 - -fun test() { - foo1(::bar1) - foo1(::bar2) - - foo1(::bar3) // Should be ambiguity -} diff --git a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.kt b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.kt index 9737580400a..fbcbf56ace7 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +SuspendConversion // !DIAGNOSTICS: -UNUSED_PARAMETER diff --git a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithReferenceAdaptation.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithReferenceAdaptation.fir.kt index 24ebf2b341e..98f99688e36 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithReferenceAdaptation.fir.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithReferenceAdaptation.fir.kt @@ -14,8 +14,8 @@ fun unitCoercionAndDefaults(f: suspend () -> Unit) {} fun all(s: String = ""): Int = 0 fun test() { - unitCoercion(::foo) - defaults(::bar) + unitCoercion(::foo) + defaults(::bar) varargs(::baz) - unitCoercionAndDefaults(::all) + unitCoercionAndDefaults(::all) } diff --git a/compiler/testData/diagnostics/tests/unitConversion/chainedFunSuspendUnitConversion.fir.kt b/compiler/testData/diagnostics/tests/unitConversion/chainedFunSuspendUnitConversion.fir.kt index 8872067d293..be9c72b2297 100644 --- a/compiler/testData/diagnostics/tests/unitConversion/chainedFunSuspendUnitConversion.fir.kt +++ b/compiler/testData/diagnostics/tests/unitConversion/chainedFunSuspendUnitConversion.fir.kt @@ -14,5 +14,5 @@ abstract class SubInt : () -> Int fun test(f: () -> String, s: SubInt) { foo(f) foo(s) - foo(::bar) + foo(::bar) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/unitConversion/chainedUnitSuspendConversion.fir.kt b/compiler/testData/diagnostics/tests/unitConversion/chainedUnitSuspendConversion.fir.kt index 0166b5e4859..3b7720dce05 100644 --- a/compiler/testData/diagnostics/tests/unitConversion/chainedUnitSuspendConversion.fir.kt +++ b/compiler/testData/diagnostics/tests/unitConversion/chainedUnitSuspendConversion.fir.kt @@ -8,7 +8,7 @@ fun bar(): String = "" abstract class SubInt : () -> Int fun test(g: () -> Double, s: SubInt) { - foo(::bar) + foo(::bar) foo(g) foo(s) } \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/callableReferences/suspendConversion.fir.txt b/compiler/testData/ir/irText/expressions/callableReferences/suspendConversion.fir.txt index f5cf106b38a..5cca1b0d2c3 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/suspendConversion.fir.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/suspendConversion.fir.txt @@ -59,30 +59,50 @@ FILE fqName: fileName:/suspendConversion.kt fn: FUNCTION_REFERENCE 'public final fun foo0 (): kotlin.Unit [suspend] declared in ' type=kotlin.reflect.KSuspendFunction0 origin=null reflectionTarget= FUN name:testSuspendPlain visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - FUNCTION_REFERENCE 'public final fun foo1 (): kotlin.Unit declared in ' type=kotlin.reflect.KFunction0 origin=null reflectionTarget= + CALL 'public final fun useSuspend (fn: kotlin.coroutines.SuspendFunction0): kotlin.Unit declared in ' type=kotlin.Unit origin=null + fn: FUN_EXPR type=kotlin.coroutines.SuspendFunction0 origin=ADAPTED_FUNCTION_REFERENCE + FUN ADAPTER_FOR_CALLABLE_REFERENCE name:foo1 visibility:local modality:FINAL <> () returnType:kotlin.Unit [suspend] + BLOCK_BODY + CALL 'public final fun foo1 (): kotlin.Unit declared in ' type=kotlin.Unit origin=null FUN name:testSuspendWithArgs visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - FUNCTION_REFERENCE 'public final fun fooInt (x: kotlin.Int): kotlin.Unit declared in ' type=kotlin.reflect.KFunction1 origin=null reflectionTarget= + CALL 'public final fun useSuspendInt (fn: kotlin.coroutines.SuspendFunction1): kotlin.Unit declared in ' type=kotlin.Unit origin=null + fn: FUN_EXPR type=kotlin.coroutines.SuspendFunction1 origin=ADAPTED_FUNCTION_REFERENCE + FUN ADAPTER_FOR_CALLABLE_REFERENCE name:fooInt visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:kotlin.Int + BLOCK_BODY + CALL 'public final fun fooInt (x: kotlin.Int): kotlin.Unit declared in ' type=kotlin.Unit origin=null + x: GET_VAR 'p0: kotlin.Int declared in .testSuspendWithArgs.fooInt' type=kotlin.Int origin=null FUN name:testWithVararg visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - FUNCTION_REFERENCE 'public final fun foo2 (vararg xs: kotlin.Int): kotlin.Unit declared in ' type=kotlin.reflect.KFunction1 origin=null reflectionTarget= + CALL 'public final fun useSuspend (fn: kotlin.coroutines.SuspendFunction0): kotlin.Unit declared in ' type=kotlin.Unit origin=null + fn: FUN_EXPR type=kotlin.coroutines.SuspendFunction0 origin=ADAPTED_FUNCTION_REFERENCE + FUN ADAPTER_FOR_CALLABLE_REFERENCE name:foo2 visibility:local modality:FINAL <> () returnType:kotlin.Unit [suspend] + BLOCK_BODY + CALL 'public final fun foo2 (vararg xs: kotlin.Int): kotlin.Unit declared in ' type=kotlin.Unit origin=null FUN name:testWithVarargMapped visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY ERROR_CALL 'Unresolved reference: #' type=IrErrorType FUNCTION_REFERENCE 'public final fun foo2 (vararg xs: kotlin.Int): kotlin.Unit declared in ' type=kotlin.reflect.KFunction1 origin=null reflectionTarget= FUN name:testWithCoercionToUnit visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - FUNCTION_REFERENCE 'public final fun foo3 (): kotlin.Int declared in ' type=kotlin.reflect.KFunction0 origin=null reflectionTarget= + CALL 'public final fun useSuspend (fn: kotlin.coroutines.SuspendFunction0): kotlin.Unit declared in ' type=kotlin.Unit origin=null + fn: FUN_EXPR type=kotlin.coroutines.SuspendFunction0 origin=ADAPTED_FUNCTION_REFERENCE + FUN ADAPTER_FOR_CALLABLE_REFERENCE name:foo3 visibility:local modality:FINAL <> () returnType:kotlin.Unit [suspend] + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun foo3 (): kotlin.Unit [suspend] declared in .testWithCoercionToUnit' + CALL 'public final fun foo3 (): kotlin.Int declared in ' type=kotlin.Int origin=null FUN name:testWithDefaults visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - FUNCTION_REFERENCE 'public final fun foo4 (i: kotlin.Int): kotlin.Unit declared in ' type=kotlin.reflect.KFunction1 origin=null reflectionTarget= + CALL 'public final fun useSuspend (fn: kotlin.coroutines.SuspendFunction0): kotlin.Unit declared in ' type=kotlin.Unit origin=null + fn: FUN_EXPR type=kotlin.coroutines.SuspendFunction0 origin=ADAPTED_FUNCTION_REFERENCE + FUN ADAPTER_FOR_CALLABLE_REFERENCE name:foo4 visibility:local modality:FINAL <> () returnType:kotlin.Unit [suspend] + BLOCK_BODY + CALL 'public final fun foo4 (i: kotlin.Int): kotlin.Unit declared in ' type=kotlin.Unit origin=null FUN name:testWithBoundReceiver visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - FUNCTION_REFERENCE 'public final fun bar (): kotlin.Unit declared in .C' type=kotlin.reflect.KFunction0 origin=null reflectionTarget= - $this: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .C' type=.C origin=null + CALL 'public final fun useSuspend (fn: kotlin.coroutines.SuspendFunction0): kotlin.Unit declared in ' type=kotlin.Unit origin=null + fn: FUN_EXPR type=kotlin.coroutines.SuspendFunction0 origin=ADAPTED_FUNCTION_REFERENCE + FUN ADAPTER_FOR_CALLABLE_REFERENCE name:bar visibility:local modality:FINAL <> () returnType:kotlin.Unit [suspend] + BLOCK_BODY + CALL 'public final fun bar (): kotlin.Unit declared in .C' type=kotlin.Unit origin=null