From 6de8ba40c1c472545874247be45b7ac794882940 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Tue, 8 Sep 2020 14:59:28 -0700 Subject: [PATCH] FIR: initial support of suspend conversion on arguments --- .../kotlin/fir/backend/ConversionUtils.kt | 13 +- .../generators/CallAndReferenceGenerator.kt | 174 +++++++++++++-- .../kotlin/fir/resolve/calls/Arguments.kt | 24 ++- .../fir/resolve/inference/InferenceUtils.kt | 26 ++- .../suspendConversion/onArgument.kt | 1 - .../basicSuspendConversion.fir.kt | 6 +- .../basicSuspendConversionGenerics.fir.kt | 12 +- ...uspendConversionForSimpleExpression.fir.kt | 2 +- ...overloadResolutionBySuspendModifier.fir.kt | 2 +- .../severalConversionsInOneCall.fir.kt | 11 - .../severalConversionsInOneCall.kt | 1 + ...spendAndFunConversionInDisabledMode.fir.kt | 4 +- .../suspendConversionCompatibility.fir.kt | 2 +- .../suspendConversionDisabled.fir.kt | 6 +- .../suspendConversionOnVarargElements.fir.kt | 20 -- .../suspendConversionOnVarargElements.kt | 1 + .../coroutines/lambdaExpectedType.fir.kt | 4 +- .../functionVsSuspendFunction.fir.kt | 4 +- ...endConversionOnArbitraryExpression.fir.txt | 199 +++++++++++++++--- 19 files changed, 393 insertions(+), 119 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/suspendConversion/severalConversionsInOneCall.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.fir.kt diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index 013351245e2..fd4667e5950 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -477,14 +477,21 @@ fun Fir2IrComponents.createSafeCallConstruction( } } -fun Fir2IrComponents.createTemporaryVariableForSafeCallConstruction( +fun Fir2IrComponents.createTemporaryVariable( receiverExpression: IrExpression, - conversionScope: Fir2IrConversionScope + conversionScope: Fir2IrConversionScope, + nameHint: String? = null ): Pair { - val receiverVariable = declarationStorage.declareTemporaryVariable(receiverExpression, "safe_receiver").apply { + val receiverVariable = declarationStorage.declareTemporaryVariable(receiverExpression, nameHint).apply { parent = conversionScope.parentFromStack() } val variableSymbol = receiverVariable.symbol return Pair(receiverVariable, variableSymbol) } + +fun Fir2IrComponents.createTemporaryVariableForSafeCallConstruction( + receiverExpression: IrExpression, + conversionScope: Fir2IrConversionScope +): Pair = + createTemporaryVariable(receiverExpression, conversionScope, "safe_receiver") 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 5d61f4b41bf..64af973a1dc 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 @@ -40,6 +40,8 @@ import org.jetbrains.kotlin.psi.KtPropertyDelegate import org.jetbrains.kotlin.psi2ir.generators.hasNoSideEffects import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredCallableSymbols class CallAndReferenceGenerator( private val components: Fir2IrComponents, @@ -192,6 +194,7 @@ class CallAndReferenceGenerator( return coneType.toIrType() as IrSimpleType } + // TODO: refactor to share some logic with suspend conversion on arguments (maybe introduce AdapterGenerator?) private fun generateAdaptedCallableReference( callableReferenceAccess: FirCallableReferenceAccess, explicitReceiverExpression: IrExpression?, @@ -205,10 +208,10 @@ class CallAndReferenceGenerator( val boundDispatchReceiver = callableReferenceAccess.findBoundReceiver(explicitReceiverExpression, isDispatch = true) val boundExtensionReceiver = callableReferenceAccess.findBoundReceiver(explicitReceiverExpression, isDispatch = false) - val irAdapterFunction = createAdapterFunction( + val irAdapterFunction = createAdapterFunctionForCallableReference( callableReferenceAccess, startOffset, endOffset, firAdaptee!!, adaptee, type, boundDispatchReceiver, boundExtensionReceiver ) - val irCall = createAdapteeCall( + val irCall = createAdapteeCallForCallableReference( callableReferenceAccess, adapteeSymbol, irAdapterFunction, boundDispatchReceiver, boundExtensionReceiver ) irAdapterFunction.body = irFactory.createBlockBody(startOffset, endOffset) { @@ -231,8 +234,7 @@ class CallAndReferenceGenerator( if (boundReceiver.isSafeToUseWithoutCopying()) { irAdapterRef.extensionReceiver = boundReceiver } else { - val (irVariable, irVariableSymbol) = - createTemporaryVariableForSafeCallConstruction(boundReceiver.deepCopyWithSymbols(), conversionScope) + val (irVariable, irVariableSymbol) = createTemporaryVariable(boundReceiver.deepCopyWithSymbols(), conversionScope) irAdapterRef.extensionReceiver = IrGetValueImpl(startOffset, endOffset, irVariableSymbol) statements.add(irVariable) } @@ -244,7 +246,7 @@ class CallAndReferenceGenerator( } } - private fun createAdapterFunction( + private fun createAdapterFunctionForCallableReference( callableReferenceAccess: FirCallableReferenceAccess, startOffset: Int, endOffset: Int, @@ -288,10 +290,22 @@ class CallAndReferenceGenerator( error("Bound callable references can't have both receivers: ${callableReferenceAccess.render()}") else -> irAdapterFunction.extensionReceiverParameter = - createAdapterParameter(irAdapterFunction, Name.identifier("receiver"), -1, boundReceiver.type) + createAdapterParameter( + irAdapterFunction, + Name.identifier("receiver"), + index = -1, + boundReceiver.type, + IrDeclarationOrigin.ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE + ) } irAdapterFunction.valueParameters += parameterTypes.mapIndexed { index, parameterType -> - createAdapterParameter(irAdapterFunction, Name.identifier("p$index"), index, parameterType) + createAdapterParameter( + irAdapterFunction, + Name.identifier("p$index"), + index, + parameterType, + IrDeclarationOrigin.ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE + ) } symbolTable.leaveScope(irAdapterFunction) @@ -304,17 +318,18 @@ class CallAndReferenceGenerator( adapterFunction: IrFunction, name: Name, index: Int, - type: IrType + type: IrType, + origin: IrDeclarationOrigin ): 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 + startOffset, endOffset, origin, descriptor, type ) { irAdapterParameterSymbol -> irFactory.createValueParameter( startOffset, endOffset, - IrDeclarationOrigin.ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE, + origin, irAdapterParameterSymbol, name, index, @@ -329,7 +344,10 @@ class CallAndReferenceGenerator( } } - private fun createAdapteeCall( + private fun IrValueDeclaration.toIrGetValue(startOffset: Int, endOffset: Int): IrGetValue = + IrGetValueImpl(startOffset, endOffset, this.type, this.symbol) + + private fun createAdapteeCallForCallableReference( callableReferenceAccess: FirCallableReferenceAccess, adapteeSymbol: IrFunctionSymbol, adapterFunction: IrFunction, @@ -381,9 +399,6 @@ class CallAndReferenceGenerator( } } - fun IrValueParameter.toGetValue(): IrGetValue = - IrGetValueImpl(startOffset, endOffset, this.type, this.symbol) - adapteeFunction.valueParameters.mapIndexed { index, valueParameter -> when { valueParameter.isVararg -> { @@ -394,7 +409,8 @@ class CallAndReferenceGenerator( IrVarargImpl(startOffset, endOffset, valueParameter.type, valueParameter.varargElementType!!) var neitherArrayNorSpread = false while (adapterParameterIndex < adapterFunction.valueParameters.size) { - val irValueArgument = adapterFunction.valueParameters[adapterParameterIndex].toGetValue() + val irValueArgument = + adapterFunction.valueParameters[adapterParameterIndex].toIrGetValue(startOffset, endOffset) if (irValueArgument.type == valueParameter.type) { adaptedValueArgument.addElement(IrSpreadElementImpl(startOffset, endOffset, irValueArgument)) adapterParameterIndex++ @@ -418,7 +434,9 @@ class CallAndReferenceGenerator( irCall.putValueArgument(index, null) } else -> { - irCall.putValueArgument(index, adapterFunction.valueParameters[adapterParameterIndex++].toGetValue()) + irCall.putValueArgument( + index, adapterFunction.valueParameters[adapterParameterIndex++].toIrGetValue(startOffset, endOffset) + ) } } } @@ -714,6 +732,7 @@ class CallAndReferenceGenerator( val argumentExpression = visitor.convertToIrExpression(argument) .applySamConversionIfNeeded(argument, valueParameter) + .applySuspendConversionIfNeeded(argument, valueParameter) .applyAssigningArrayElementsToVarargInNamedForm(argument, valueParameter) putValueArgument(index, argumentExpression) } @@ -755,6 +774,7 @@ class CallAndReferenceGenerator( val irArgument = visitor.convertToIrExpression(argument) .applySamConversionIfNeeded(argument, parameter) + .applySuspendConversionIfNeeded(argument, parameter) .applyAssigningArrayElementsToVarargInNamedForm(argument, parameter) if (irArgument.hasNoSideEffects()) { putValueArgument(parameterIndex, irArgument) @@ -773,6 +793,7 @@ class CallAndReferenceGenerator( val argumentExpression = visitor.convertToIrExpression(argument, annotationMode) .applySamConversionIfNeeded(argument, parameter) + .applySuspendConversionIfNeeded(argument, parameter) .applyAssigningArrayElementsToVarargInNamedForm(argument, parameter) putValueArgument(valueParameters.indexOf(parameter), argumentExpression) } @@ -827,6 +848,127 @@ class CallAndReferenceGenerator( return argument.isFunctional(session) } + // TODO: refactor to share some logic with suspend conversion for callable reference (maybe introduce AdapterGenerator?) + private fun IrExpression.applySuspendConversionIfNeeded( + argument: FirExpression, + parameter: FirValueParameter? + ): IrExpression { + if (this is IrBlock && origin == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE) { + return this + } + if (parameter == null || !needSuspendConversion(argument, parameter)) { + return this + } + + val suspendConvertedType = parameter.returnTypeRef.toIrType() as IrSimpleType + val returnType = suspendConvertedType.arguments.last().typeOrNull!! + val invokeSymbol = + (argument.typeRef.coneType as? ConeClassLikeType)?.lookupTag?.classId + ?.let { classId -> + session.firSymbolProvider + .getClassDeclaredCallableSymbols(classId, Name.identifier("invoke")) + .filterIsInstance>() + .find { firFunctionSymbol -> + firFunctionSymbol.fir.valueParameters.size == suspendConvertedType.arguments.size - 1 + }?.let { firFunctionSymbol -> + declarationStorage.getIrFunctionSymbol(firFunctionSymbol) as? IrSimpleFunctionSymbol + } + } ?: return this + return argument.convertWithOffsets { startOffset, endOffset -> + val irAdapterFunction = createAdapterFunctionForArgument(startOffset, endOffset, suspendConvertedType) + // TODO: Should be able to reuse `this` if that is an immutable IrGetValue + val irArgumentValue = createTemporaryVariable(this, conversionScope).first + val irCall = createAdapteeCallForArgument(startOffset, endOffset, irAdapterFunction, invokeSymbol, irArgumentValue) + irAdapterFunction.body = irFactory.createBlockBody(startOffset, endOffset) { + if (returnType.isUnit()) { + statements.add(irCall) + } else { + statements.add(IrReturnImpl(startOffset, endOffset, irBuiltIns.nothingType, irAdapterFunction.symbol, irCall)) + } + } + + val statements = SmartList() + statements.add(irArgumentValue) + statements.add( + IrFunctionExpressionImpl( + startOffset, endOffset, suspendConvertedType, irAdapterFunction, IrStatementOrigin.SUSPEND_CONVERSION + ) + ) + IrBlockImpl(startOffset, endOffset, suspendConvertedType, IrStatementOrigin.SUSPEND_CONVERSION, statements) + } + } + + private fun needSuspendConversion(argument: FirExpression, parameter: FirValueParameter): Boolean = + // TODO: should refer to LanguageVersionSettings.SuspendConversion + parameter.returnTypeRef.coneType.isSuspendFunctionType(session) && + argument.typeRef.coneType.isBuiltinFunctionalType(session) && + !argument.typeRef.coneType.isSuspendFunctionType(session) + + private fun createAdapterFunctionForArgument( + startOffset: Int, + endOffset: Int, + 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_SUSPEND_CONVERSION, + irAdapterSymbol, + // TODO: need a better way to avoid name clash + Name.identifier("suspendConversion"), + DescriptorVisibilities.LOCAL, + Modality.FINAL, + returnType, + isInline = false, + isExternal = false, + isTailrec = false, + isSuspend = true, + isOperator = false, + isInfix = false, + isExpect = false, + isFakeOverride = false + ).also { irAdapterFunction -> + adapterFunctionDescriptor.bind(irAdapterFunction) + symbolTable.enterScope(irAdapterFunction) + irAdapterFunction.valueParameters += parameterTypes.mapIndexed { index, parameterType -> + createAdapterParameter( + irAdapterFunction, + Name.identifier("p$index"), + index, + parameterType, + IrDeclarationOrigin.ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION + ) + } + symbolTable.leaveScope(irAdapterFunction) + irAdapterFunction.parent = conversionScope.parent()!! + } + } + } + + private fun createAdapteeCallForArgument( + startOffset: Int, + endOffset: Int, + adapterFunction: IrFunction, + invokeSymbol: IrSimpleFunctionSymbol, + irCapturedValue: IrValueDeclaration + ): IrExpression { + val irCall = IrCallImpl( + startOffset, endOffset, + adapterFunction.returnType, + invokeSymbol, + typeArgumentsCount = 0, + valueArgumentsCount = adapterFunction.valueParameters.size + ) + irCall.dispatchReceiver = irCapturedValue.toIrGetValue(startOffset, endOffset) + for (irAdapterParameter in adapterFunction.valueParameters) { + irCall.putValueArgument(irAdapterParameter.index, irAdapterParameter.toIrGetValue(startOffset, endOffset)) + } + return irCall + } + private fun IrExpression.applyAssigningArrayElementsToVarargInNamedForm( argument: FirExpression, parameter: FirValueParameter? diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt index 0c0a7006ba5..f099e320355 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt @@ -11,10 +11,9 @@ import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference +import org.jetbrains.kotlin.fir.resolve.createFunctionalType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType -import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType -import org.jetbrains.kotlin.fir.resolve.inference.preprocessCallableReference -import org.jetbrains.kotlin.fir.resolve.inference.preprocessLambdaArgument +import org.jetbrains.kotlin.fir.resolve.inference.* import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedTypeDeclaration @@ -233,12 +232,29 @@ fun Candidate.resolvePlainArgumentType( val session = context.session val capturedType = prepareCapturedType(argumentType, context) - val argumentTypeForApplicabilityCheck = + var argumentTypeForApplicabilityCheck = if (useNullableArgumentType) capturedType.withNullability(ConeNullability.NULLABLE, session.typeContext) else capturedType + // If the argument is of functional type and the expected type is a suspend function type, we need to do "suspend conversion." + // TODO: should refer to LanguageVersionSettings.SuspendConversion + // TODO: should prefer another candidate without suspend conversion when ambiguous + if (expectedType?.isSuspendFunctionType(session) == true && + argumentTypeForApplicabilityCheck.isBuiltinFunctionalType(session) && + !argumentTypeForApplicabilityCheck.isSuspendFunctionType(session) + ) { + val typeParameters = argumentTypeForApplicabilityCheck.typeArguments.map { it as ConeKotlinType } + argumentTypeForApplicabilityCheck = + createFunctionalType( + typeParameters.dropLast(1), null, typeParameters.last(), + isSuspend = true, + isKFunctionType = argumentTypeForApplicabilityCheck.isKFunctionType(session) + ) + substitutor.substituteOrSelf(argumentTypeForApplicabilityCheck) + } + checkApplicabilityForArgumentType( csBuilder, argumentTypeForApplicabilityCheck, expectedType, position, isReceiver, isDispatch, sink, context ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt index 2f8a0a879ac..eee1767d08c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt @@ -16,31 +16,35 @@ import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract @OptIn(ExperimentalContracts::class) -fun ConeKotlinType.isBuiltinFunctionalType(session: FirSession): Boolean { +private fun ConeKotlinType.functionClassKind(session: FirSession): FunctionClassKind? { contract { - returns(true) implies (this@isBuiltinFunctionalType is ConeClassLikeType) + returns(true) implies (this@functionClassKind is ConeClassLikeType) } - if (this !is ConeClassLikeType) return false + if (this !is ConeClassLikeType) return null val classId = fullyExpandedType(session).lookupTag.classId - val kind = FunctionClassKind.byClassNamePrefix(classId.packageFqName, classId.relativeClassName.asString()) ?: return false + return FunctionClassKind.byClassNamePrefix(classId.packageFqName, classId.relativeClassName.asString()) +} + +fun ConeKotlinType.isBuiltinFunctionalType(session: FirSession): Boolean { + val kind = functionClassKind(session) ?: return false return kind == FunctionClassKind.Function || kind == FunctionClassKind.KFunction || kind == FunctionClassKind.SuspendFunction || kind == FunctionClassKind.KSuspendFunction } -@OptIn(ExperimentalContracts::class) fun ConeKotlinType.isSuspendFunctionType(session: FirSession): Boolean { - contract { - returns(true) implies (this@isSuspendFunctionType is ConeClassLikeType) - } - if (this !is ConeClassLikeType) return false - val classId = this.fullyExpandedType(session).lookupTag.classId - val kind = FunctionClassKind.byClassNamePrefix(classId.packageFqName, classId.relativeClassName.asString()) ?: return false + val kind = functionClassKind(session) ?: return false return kind == FunctionClassKind.SuspendFunction || kind == FunctionClassKind.KSuspendFunction } +fun ConeKotlinType.isKFunctionType(session: FirSession): Boolean { + val kind = functionClassKind(session) ?: return false + return kind == FunctionClassKind.KFunction || + kind == FunctionClassKind.KSuspendFunction +} + fun ConeKotlinType.receiverType(expectedTypeRef: FirTypeRef?, session: FirSession): ConeKotlinType? { if (isBuiltinFunctionalType(session) && expectedTypeRef?.isExtensionFunctionType(session) == true) { return (this.fullyExpandedType(session).typeArguments.first() as ConeKotlinTypeProjection).type diff --git a/compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt b/compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt index f08c81ae1d5..ae5fc50b991 100644 --- a/compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt +++ b/compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt @@ -2,7 +2,6 @@ // WITH_RUNTIME // WITH_COROUTINES // IGNORE_BACKEND: JVM, NATIVE -// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_LIGHT_ANALYSIS import helpers.* diff --git a/compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversion.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversion.fir.kt index cde39929f37..da4be44f525 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversion.fir.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversion.fir.kt @@ -14,9 +14,9 @@ fun test( foo1 { "str" } foo1(f0) - foo1(f1) - foo2(f2) - foo3(f3) + foo1(f1) + foo2(f2) + foo3(f3) foo1(f2) foo1(f3) diff --git a/compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionGenerics.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionGenerics.fir.kt index 5a8e1071bfc..e1c576a8bfd 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionGenerics.fir.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionGenerics.fir.kt @@ -10,21 +10,21 @@ fun foo3(f: suspend (T) -> K): Inv2 = TODO() fun id(e: I): I = e fun test(f: (Int) -> String, g: () -> String) { - val a0 = foo1(f) + val a0 = foo1(f) a0 - val a1 = foo2(g) + val a1 = foo2(g) a1 - val a2 = foo3(f) + val a2 = foo3(f) a2 - val a3 = foo1(id(f)) + val a3 = foo1(id(f)) a3 - val a4 = foo2(id(g)) + val a4 = foo2(id(g)) a4 - val a5 = foo3(id(f)) + val a5 = foo3(id(f)) a5 } diff --git a/compiler/testData/diagnostics/tests/suspendConversion/chainedFunSuspendConversionForSimpleExpression.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/chainedFunSuspendConversionForSimpleExpression.fir.kt index 56f7a61dace..aaf124a2478 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/chainedFunSuspendConversionForSimpleExpression.fir.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/chainedFunSuspendConversionForSimpleExpression.fir.kt @@ -9,6 +9,6 @@ fun foo(s: SuspendRunnable) {} fun test(f: () -> Unit) { foo { } - foo(f) + foo(f) } diff --git a/compiler/testData/diagnostics/tests/suspendConversion/overloadResolutionBySuspendModifier.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/overloadResolutionBySuspendModifier.fir.kt index 8e1492e8364..286713a41be 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/overloadResolutionBySuspendModifier.fir.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/overloadResolutionBySuspendModifier.fir.kt @@ -14,6 +14,6 @@ fun test1() { // candidate without suspend conversions is more specific fun test2(f: () -> Int, g: suspend () -> Int) { - foo(f) + foo(f) foo(g) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/suspendConversion/severalConversionsInOneCall.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/severalConversionsInOneCall.fir.kt deleted file mode 100644 index 5a08eb3ccb9..00000000000 --- a/compiler/testData/diagnostics/tests/suspendConversion/severalConversionsInOneCall.fir.kt +++ /dev/null @@ -1,11 +0,0 @@ -// !LANGUAGE: +SuspendConversion -// !DIAGNOSTICS: -UNUSED_PARAMETER - -fun foo(f: () -> String, g: suspend () -> String, h: suspend () -> String) {} - -fun test(f: () -> String, g: suspend () -> String) { - foo(f, f, f) - foo(f, { "str" }, f) - foo(f, f, g) - foo(f, g, g) -} diff --git a/compiler/testData/diagnostics/tests/suspendConversion/severalConversionsInOneCall.kt b/compiler/testData/diagnostics/tests/suspendConversion/severalConversionsInOneCall.kt index dd2768745b3..48b263c005c 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/severalConversionsInOneCall.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/severalConversionsInOneCall.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +SuspendConversion // !DIAGNOSTICS: -UNUSED_PARAMETER diff --git a/compiler/testData/diagnostics/tests/suspendConversion/suspendAndFunConversionInDisabledMode.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/suspendAndFunConversionInDisabledMode.fir.kt index c1c9afa394e..99e9f633398 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/suspendAndFunConversionInDisabledMode.fir.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/suspendAndFunConversionInDisabledMode.fir.kt @@ -12,7 +12,7 @@ object Test1 { fun call(r: SuspendRunnable) {} fun bar(f: () -> Unit) { - call(f) + call(f) } } } @@ -24,7 +24,7 @@ object Test2 { fun call(r: SuspendRunnable) {} fun bar(f: () -> Unit) { - call(f) + call(f) } } } diff --git a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionCompatibility.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionCompatibility.fir.kt index 17ba2c88e64..94f91433563 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionCompatibility.fir.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionCompatibility.fir.kt @@ -8,7 +8,7 @@ object Test1 { fun foo(f: suspend () -> Unit) {} fun test(g: () -> Unit) { - foo(g) + foo(g) } } } diff --git a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.fir.kt index a507eae99b3..fb5b1104d95 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.fir.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.fir.kt @@ -16,9 +16,9 @@ fun test( foo1 { "str" } foo1(f0) - foo1(f1) - foo2(f2) - foo3(f3) + foo1(f1) + foo2(f2) + foo3(f3) foo1(::bar) diff --git a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.fir.kt deleted file mode 100644 index 8d4d76c4618..00000000000 --- a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.fir.kt +++ /dev/null @@ -1,20 +0,0 @@ -// !LANGUAGE: +SuspendConversion -// !DIAGNOSTICS: -UNUSED_PARAMETER - -fun useSuspendVararg(vararg sfn: suspend () -> Unit) {} - -fun testSuspendConversionInVarargElementsSome( - sf1: suspend () -> Unit, - f2: () -> Unit, - sf3: suspend () -> Unit -) { - useSuspendVararg(sf1, f2, sf3) -} - -fun testSuspendConversionInVarargElementsAll( - f1: () -> Unit, - f2: () -> Unit, - f3: () -> Unit -) { - useSuspendVararg(f1, f2, f3) -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.kt b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.kt index edaf3ee644d..08ed73f4bab 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +SuspendConversion // !DIAGNOSTICS: -UNUSED_PARAMETER diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/lambdaExpectedType.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/lambdaExpectedType.fir.kt index c27814f0caa..e45e7c3aa02 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/lambdaExpectedType.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/lambdaExpectedType.fir.kt @@ -21,7 +21,7 @@ fun foo() { builder { 1 } val x = { 1 } - builder(x) + builder(x) builder({1} as (suspend () -> Int)) var i: Int = 1 @@ -32,7 +32,7 @@ fun foo() { genericBuilder { "" } val y = { 1 } - genericBuilder(y) + genericBuilder(y) unitBuilder {} unitBuilder { 1 } diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendFunctionType/functionVsSuspendFunction.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendFunctionType/functionVsSuspendFunction.fir.kt index 2b700c28389..b85141c411a 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendFunctionType/functionVsSuspendFunction.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendFunctionType/functionVsSuspendFunction.fir.kt @@ -8,12 +8,12 @@ fun ambiguous(sfn: suspend () -> Unit) = sfn fun ambiguous(fn: () -> Unit) = fn fun test1(sfn: suspend () -> Unit) = useFn(sfn) -fun test2(fn: () -> Unit) = useSuspendFn(fn) +fun test2(fn: () -> Unit) = useSuspendFn(fn) fun test3(sfn: suspend () -> Unit) = useSuspendFn(sfn) fun test4(): suspend () -> Unit = useSuspendFn {} fun test5() = useSuspendFn {} fun test5(sfn: suspend () -> Unit) = ambiguous(sfn) -fun test6(fn: () -> Unit) = ambiguous(fn) +fun test6(fn: () -> Unit) = ambiguous(fn) fun test7(): () -> Unit = ambiguous {} \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/suspendConversionOnArbitraryExpression.fir.txt b/compiler/testData/ir/irText/expressions/suspendConversionOnArbitraryExpression.fir.txt index 757bd22a5fd..3b4ee75964b 100644 --- a/compiler/testData/ir/irText/expressions/suspendConversionOnArbitraryExpression.fir.txt +++ b/compiler/testData/ir/irText/expressions/suspendConversionOnArbitraryExpression.fir.txt @@ -27,80 +27,208 @@ FILE fqName: fileName:/suspendConversionOnArbitraryExpression.kt FUN name:testSimple visibility:public modality:FINAL <> (fn:kotlin.Function0) returnType:kotlin.Unit VALUE_PARAMETER name:fn index:0 type:kotlin.Function0 BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - GET_VAR 'fn: kotlin.Function0 declared in .testSimple' type=kotlin.Function0 origin=null + CALL 'public final fun useSuspend (sfn: kotlin.coroutines.SuspendFunction0): kotlin.Unit declared in ' type=kotlin.Unit origin=null + sfn: BLOCK type=kotlin.coroutines.SuspendFunction0 origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Function0 [val] + GET_VAR 'fn: kotlin.Function0 declared in .testSimple' type=kotlin.Function0 origin=null + FUN_EXPR type=kotlin.coroutines.SuspendFunction0 origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> () returnType:kotlin.Unit [suspend] + BLOCK_BODY + CALL 'public abstract fun invoke (): R of kotlin.Function0 [operator] declared in kotlin.Function0' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_0: kotlin.Function0 [val] declared in .testSimple' type=kotlin.Function0 origin=null FUN name:testSimpleNonVal visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - CALL 'public final fun produceFun (): kotlin.Function0 declared in ' type=kotlin.Function0 origin=null + CALL 'public final fun useSuspend (sfn: kotlin.coroutines.SuspendFunction0): kotlin.Unit declared in ' type=kotlin.Unit origin=null + sfn: BLOCK type=kotlin.coroutines.SuspendFunction0 origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Function0 [val] + CALL 'public final fun produceFun (): kotlin.Function0 declared in ' type=kotlin.Function0 origin=null + FUN_EXPR type=kotlin.coroutines.SuspendFunction0 origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> () returnType:kotlin.Unit [suspend] + BLOCK_BODY + CALL 'public abstract fun invoke (): R of kotlin.Function0 [operator] declared in kotlin.Function0' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_1: kotlin.Function0 [val] declared in .testSimpleNonVal' type=kotlin.Function0 origin=null FUN name:testExtAsExt visibility:public modality:FINAL <> (fn:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1) returnType:kotlin.Unit VALUE_PARAMETER name:fn index:0 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 declared in .testExtAsExt' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 origin=null + CALL 'public final fun useSuspendExt (sfn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1): kotlin.Unit declared in ' type=kotlin.Unit origin=null + sfn: BLOCK type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1 origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 [val] + GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 declared in .testExtAsExt' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 origin=null + FUN_EXPR type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1 origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:kotlin.Int + BLOCK_BODY + CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_2: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 [val] declared in .testExtAsExt' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 origin=null + p1: GET_VAR 'p0: kotlin.Int declared in .testExtAsExt.suspendConversion' type=kotlin.Int origin=null FUN name:testExtAsSimple visibility:public modality:FINAL <> (fn:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1) returnType:kotlin.Unit VALUE_PARAMETER name:fn index:0 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 declared in .testExtAsSimple' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 origin=null + CALL 'public final fun useSuspendArg (sfn: kotlin.coroutines.SuspendFunction1): kotlin.Unit declared in ' type=kotlin.Unit origin=null + sfn: BLOCK type=kotlin.coroutines.SuspendFunction1 origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 [val] + GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 declared in .testExtAsSimple' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 origin=null + FUN_EXPR type=kotlin.coroutines.SuspendFunction1 origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:kotlin.Int + BLOCK_BODY + CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_3: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 [val] declared in .testExtAsSimple' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 origin=null + p1: GET_VAR 'p0: kotlin.Int declared in .testExtAsSimple.suspendConversion' type=kotlin.Int origin=null FUN name:testSimpleAsExt visibility:public modality:FINAL <> (fn:kotlin.Function1) returnType:kotlin.Unit VALUE_PARAMETER name:fn index:0 type:kotlin.Function1 BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - GET_VAR 'fn: kotlin.Function1 declared in .testSimpleAsExt' type=kotlin.Function1 origin=null + CALL 'public final fun useSuspendExt (sfn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1): kotlin.Unit declared in ' type=kotlin.Unit origin=null + sfn: BLOCK type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1 origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Function1 [val] + GET_VAR 'fn: kotlin.Function1 declared in .testSimpleAsExt' type=kotlin.Function1 origin=null + FUN_EXPR type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1 origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:kotlin.Int + BLOCK_BODY + CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_4: kotlin.Function1 [val] declared in .testSimpleAsExt' type=kotlin.Function1 origin=null + p1: GET_VAR 'p0: kotlin.Int declared in .testSimpleAsExt.suspendConversion' type=kotlin.Int origin=null FUN name:testSimpleAsSimpleT visibility:public modality:FINAL <> (fn:kotlin.Function1) returnType:kotlin.Unit VALUE_PARAMETER name:fn index:0 type:kotlin.Function1 BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - GET_VAR 'fn: kotlin.Function1 declared in .testSimpleAsSimpleT' type=kotlin.Function1 origin=null + CALL 'public final fun useSuspendArgT (sfn: kotlin.coroutines.SuspendFunction1.useSuspendArgT, kotlin.Unit>): kotlin.Unit declared in ' type=kotlin.Unit origin=null + : kotlin.Int + sfn: BLOCK type=kotlin.coroutines.SuspendFunction1.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Function1 [val] + GET_VAR 'fn: kotlin.Function1 declared in .testSimpleAsSimpleT' type=kotlin.Function1 origin=null + FUN_EXPR type=kotlin.coroutines.SuspendFunction1.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of .useSuspendArgT) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of .useSuspendArgT + BLOCK_BODY + CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_5: kotlin.Function1 [val] declared in .testSimpleAsSimpleT' type=kotlin.Function1 origin=null + p1: GET_VAR 'p0: T of .useSuspendArgT declared in .testSimpleAsSimpleT.suspendConversion' type=T of .useSuspendArgT origin=null FUN name:testSimpleAsExtT visibility:public modality:FINAL <> (fn:kotlin.Function1) returnType:kotlin.Unit VALUE_PARAMETER name:fn index:0 type:kotlin.Function1 BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - GET_VAR 'fn: kotlin.Function1 declared in .testSimpleAsExtT' type=kotlin.Function1 origin=null + CALL 'public final fun useSuspendExtT (sfn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1.useSuspendExtT, kotlin.Unit>): kotlin.Unit declared in ' type=kotlin.Unit origin=null + : kotlin.Int + sfn: BLOCK type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Function1 [val] + GET_VAR 'fn: kotlin.Function1 declared in .testSimpleAsExtT' type=kotlin.Function1 origin=null + FUN_EXPR type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of .useSuspendExtT) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of .useSuspendExtT + BLOCK_BODY + CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_6: kotlin.Function1 [val] declared in .testSimpleAsExtT' type=kotlin.Function1 origin=null + p1: GET_VAR 'p0: T of .useSuspendExtT declared in .testSimpleAsExtT.suspendConversion' type=T of .useSuspendExtT origin=null FUN name:testExtAsSimpleT visibility:public modality:FINAL <> (fn:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1) returnType:kotlin.Unit VALUE_PARAMETER name:fn index:0 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 declared in .testExtAsSimpleT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 origin=null + CALL 'public final fun useSuspendArgT (sfn: kotlin.coroutines.SuspendFunction1.useSuspendArgT, kotlin.Unit>): kotlin.Unit declared in ' type=kotlin.Unit origin=null + : kotlin.Int + sfn: BLOCK type=kotlin.coroutines.SuspendFunction1.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 [val] + GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 declared in .testExtAsSimpleT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 origin=null + FUN_EXPR type=kotlin.coroutines.SuspendFunction1.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of .useSuspendArgT) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of .useSuspendArgT + BLOCK_BODY + CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_7: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 [val] declared in .testExtAsSimpleT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 origin=null + p1: GET_VAR 'p0: T of .useSuspendArgT declared in .testExtAsSimpleT.suspendConversion' type=T of .useSuspendArgT origin=null FUN name:testExtAsExtT visibility:public modality:FINAL <> (fn:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1) returnType:kotlin.Unit VALUE_PARAMETER name:fn index:0 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 declared in .testExtAsExtT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 origin=null + CALL 'public final fun useSuspendExtT (sfn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1.useSuspendExtT, kotlin.Unit>): kotlin.Unit declared in ' type=kotlin.Unit origin=null + : kotlin.Int + sfn: BLOCK type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 [val] + GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 declared in .testExtAsExtT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 origin=null + FUN_EXPR type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of .useSuspendExtT) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of .useSuspendExtT + BLOCK_BODY + CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_8: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 [val] declared in .testExtAsExtT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1 origin=null + p1: GET_VAR 'p0: T of .useSuspendExtT declared in .testExtAsExtT.suspendConversion' type=T of .useSuspendExtT origin=null FUN name:testSimpleSAsSimpleT visibility:public modality:FINAL (fn:kotlin.Function1.testSimpleSAsSimpleT, kotlin.Unit>) returnType:kotlin.Unit TYPE_PARAMETER name:S index:0 variance: superTypes:[kotlin.Any?] VALUE_PARAMETER name:fn index:0 type:kotlin.Function1.testSimpleSAsSimpleT, kotlin.Unit> BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - GET_VAR 'fn: kotlin.Function1.testSimpleSAsSimpleT, kotlin.Unit> declared in .testSimpleSAsSimpleT' type=kotlin.Function1.testSimpleSAsSimpleT, kotlin.Unit> origin=null + CALL 'public final fun useSuspendArgT (sfn: kotlin.coroutines.SuspendFunction1.useSuspendArgT, kotlin.Unit>): kotlin.Unit declared in ' type=kotlin.Unit origin=null + : S of .testSimpleSAsSimpleT + sfn: BLOCK type=kotlin.coroutines.SuspendFunction1.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:kotlin.Function1.testSimpleSAsSimpleT, kotlin.Unit> [val] + GET_VAR 'fn: kotlin.Function1.testSimpleSAsSimpleT, kotlin.Unit> declared in .testSimpleSAsSimpleT' type=kotlin.Function1.testSimpleSAsSimpleT, kotlin.Unit> origin=null + FUN_EXPR type=kotlin.coroutines.SuspendFunction1.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of .useSuspendArgT) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of .useSuspendArgT + BLOCK_BODY + CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_9: kotlin.Function1.testSimpleSAsSimpleT, kotlin.Unit> [val] declared in .testSimpleSAsSimpleT' type=kotlin.Function1.testSimpleSAsSimpleT, kotlin.Unit> origin=null + p1: GET_VAR 'p0: T of .useSuspendArgT declared in .testSimpleSAsSimpleT.suspendConversion' type=T of .useSuspendArgT origin=null FUN name:testSimpleSAsExtT visibility:public modality:FINAL (fn:kotlin.Function1.testSimpleSAsExtT, kotlin.Unit>) returnType:kotlin.Unit TYPE_PARAMETER name:S index:0 variance: superTypes:[kotlin.Any?] VALUE_PARAMETER name:fn index:0 type:kotlin.Function1.testSimpleSAsExtT, kotlin.Unit> BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - GET_VAR 'fn: kotlin.Function1.testSimpleSAsExtT, kotlin.Unit> declared in .testSimpleSAsExtT' type=kotlin.Function1.testSimpleSAsExtT, kotlin.Unit> origin=null + CALL 'public final fun useSuspendExtT (sfn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1.useSuspendExtT, kotlin.Unit>): kotlin.Unit declared in ' type=kotlin.Unit origin=null + : S of .testSimpleSAsExtT + sfn: BLOCK type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:kotlin.Function1.testSimpleSAsExtT, kotlin.Unit> [val] + GET_VAR 'fn: kotlin.Function1.testSimpleSAsExtT, kotlin.Unit> declared in .testSimpleSAsExtT' type=kotlin.Function1.testSimpleSAsExtT, kotlin.Unit> origin=null + FUN_EXPR type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of .useSuspendExtT) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of .useSuspendExtT + BLOCK_BODY + CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_10: kotlin.Function1.testSimpleSAsExtT, kotlin.Unit> [val] declared in .testSimpleSAsExtT' type=kotlin.Function1.testSimpleSAsExtT, kotlin.Unit> origin=null + p1: GET_VAR 'p0: T of .useSuspendExtT declared in .testSimpleSAsExtT.suspendConversion' type=T of .useSuspendExtT origin=null FUN name:testExtSAsSimpleT visibility:public modality:FINAL (fn:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsSimpleT, kotlin.Unit>) returnType:kotlin.Unit TYPE_PARAMETER name:S index:0 variance: superTypes:[kotlin.Any?] VALUE_PARAMETER name:fn index:0 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsSimpleT, kotlin.Unit> BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsSimpleT, kotlin.Unit> declared in .testExtSAsSimpleT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsSimpleT, kotlin.Unit> origin=null + CALL 'public final fun useSuspendArgT (sfn: kotlin.coroutines.SuspendFunction1.useSuspendArgT, kotlin.Unit>): kotlin.Unit declared in ' type=kotlin.Unit origin=null + : S of .testExtSAsSimpleT + sfn: BLOCK type=kotlin.coroutines.SuspendFunction1.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_11 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsSimpleT, kotlin.Unit> [val] + GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsSimpleT, kotlin.Unit> declared in .testExtSAsSimpleT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsSimpleT, kotlin.Unit> origin=null + FUN_EXPR type=kotlin.coroutines.SuspendFunction1.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of .useSuspendArgT) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of .useSuspendArgT + BLOCK_BODY + CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_11: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsSimpleT, kotlin.Unit> [val] declared in .testExtSAsSimpleT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsSimpleT, kotlin.Unit> origin=null + p1: GET_VAR 'p0: T of .useSuspendArgT declared in .testExtSAsSimpleT.suspendConversion' type=T of .useSuspendArgT origin=null FUN name:testExtSAsExtT visibility:public modality:FINAL (fn:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsExtT, kotlin.Unit>) returnType:kotlin.Unit TYPE_PARAMETER name:S index:0 variance: superTypes:[kotlin.Any?] VALUE_PARAMETER name:fn index:0 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsExtT, kotlin.Unit> BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsExtT, kotlin.Unit> declared in .testExtSAsExtT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsExtT, kotlin.Unit> origin=null + CALL 'public final fun useSuspendExtT (sfn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1.useSuspendExtT, kotlin.Unit>): kotlin.Unit declared in ' type=kotlin.Unit origin=null + : S of .testExtSAsExtT + sfn: BLOCK type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_12 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsExtT, kotlin.Unit> [val] + GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsExtT, kotlin.Unit> declared in .testExtSAsExtT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsExtT, kotlin.Unit> origin=null + FUN_EXPR type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of .useSuspendExtT) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of .useSuspendExtT + BLOCK_BODY + CALL 'public abstract fun invoke (p1: P1 of kotlin.Function1): R of kotlin.Function1 [operator] declared in kotlin.Function1' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_12: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsExtT, kotlin.Unit> [val] declared in .testExtSAsExtT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1.testExtSAsExtT, kotlin.Unit> origin=null + p1: GET_VAR 'p0: T of .useSuspendExtT declared in .testExtSAsExtT.suspendConversion' type=T of .useSuspendExtT origin=null FUN name:testSmartCastWithSuspendConversion visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:kotlin.Any BLOCK_BODY TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit TYPE_OP type=kotlin.Function0 origin=CAST typeOperand=kotlin.Function0 GET_VAR 'a: kotlin.Any declared in .testSmartCastWithSuspendConversion' type=kotlin.Any origin=null - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - TYPE_OP type=kotlin.Function0 origin=IMPLICIT_CAST typeOperand=kotlin.Function0 - GET_VAR 'a: kotlin.Any declared in .testSmartCastWithSuspendConversion' type=kotlin.Any origin=null + CALL 'public final fun useSuspend (sfn: kotlin.coroutines.SuspendFunction0): kotlin.Unit declared in ' type=kotlin.Unit origin=null + sfn: BLOCK type=kotlin.coroutines.SuspendFunction0 origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_13 type:kotlin.Function0 [val] + TYPE_OP type=kotlin.Function0 origin=IMPLICIT_CAST typeOperand=kotlin.Function0 + GET_VAR 'a: kotlin.Any declared in .testSmartCastWithSuspendConversion' type=kotlin.Any origin=null + FUN_EXPR type=kotlin.coroutines.SuspendFunction0 origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> () returnType:kotlin.Unit [suspend] + BLOCK_BODY + CALL 'public abstract fun invoke (): R of kotlin.Function0 [operator] declared in kotlin.Function0' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_13: kotlin.Function0 [val] declared in .testSmartCastWithSuspendConversion' type=kotlin.Function0 origin=null FUN name:testSmartCastOnVarWithSuspendConversion visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:kotlin.Any BLOCK_BODY @@ -109,9 +237,16 @@ FILE fqName: fileName:/suspendConversionOnArbitraryExpression.kt TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit TYPE_OP type=kotlin.Function0 origin=CAST typeOperand=kotlin.Function0 GET_VAR 'var b: kotlin.Any [var] declared in .testSmartCastOnVarWithSuspendConversion' type=kotlin.Any origin=null - ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit - TYPE_OP type=kotlin.Function0 origin=IMPLICIT_CAST typeOperand=kotlin.Function0 - GET_VAR 'var b: kotlin.Any [var] declared in .testSmartCastOnVarWithSuspendConversion' type=kotlin.Any origin=null + CALL 'public final fun useSuspend (sfn: kotlin.coroutines.SuspendFunction0): kotlin.Unit declared in ' type=kotlin.Unit origin=null + sfn: BLOCK type=kotlin.coroutines.SuspendFunction0 origin=SUSPEND_CONVERSION + VAR IR_TEMPORARY_VARIABLE name:tmp_14 type:kotlin.Function0 [val] + TYPE_OP type=kotlin.Function0 origin=IMPLICIT_CAST typeOperand=kotlin.Function0 + GET_VAR 'var b: kotlin.Any [var] declared in .testSmartCastOnVarWithSuspendConversion' type=kotlin.Any origin=null + FUN_EXPR type=kotlin.coroutines.SuspendFunction0 origin=SUSPEND_CONVERSION + FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> () returnType:kotlin.Unit [suspend] + BLOCK_BODY + CALL 'public abstract fun invoke (): R of kotlin.Function0 [operator] declared in kotlin.Function0' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_14: kotlin.Function0 [val] declared in .testSmartCastOnVarWithSuspendConversion' type=kotlin.Function0 origin=null FUN name:testSmartCastVsSuspendConversion visibility:public modality:FINAL <> (a:kotlin.Function0) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:kotlin.Function0 BLOCK_BODY