FIR: initial support of suspend conversion on arguments

This commit is contained in:
Jinseong Jeon
2020-09-08 14:59:28 -07:00
committed by Mikhail Glukhikh
parent 49679f3145
commit 6de8ba40c1
19 changed files with 393 additions and 119 deletions
@@ -477,14 +477,21 @@ fun Fir2IrComponents.createSafeCallConstruction(
}
}
fun Fir2IrComponents.createTemporaryVariableForSafeCallConstruction(
fun Fir2IrComponents.createTemporaryVariable(
receiverExpression: IrExpression,
conversionScope: Fir2IrConversionScope
conversionScope: Fir2IrConversionScope,
nameHint: String? = null
): Pair<IrVariable, IrValueSymbol> {
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<IrVariable, IrValueSymbol> =
createTemporaryVariable(receiverExpression, conversionScope, "safe_receiver")
@@ -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<FirFunctionSymbol<*>>()
.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<IrStatement>()
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?
@@ -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
)
@@ -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
@@ -2,7 +2,6 @@
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND: JVM, NATIVE
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_LIGHT_ANALYSIS
import helpers.*
@@ -14,9 +14,9 @@ fun test(
foo1 { "str" }
foo1(f0)
<!INAPPLICABLE_CANDIDATE!>foo1<!>(f1)
<!INAPPLICABLE_CANDIDATE!>foo2<!>(f2)
<!INAPPLICABLE_CANDIDATE!>foo3<!>(f3)
foo1(f1)
foo2(f2)
foo3(f3)
<!INAPPLICABLE_CANDIDATE!>foo1<!>(f2)
<!INAPPLICABLE_CANDIDATE!>foo1<!>(f3)
@@ -10,21 +10,21 @@ fun <T, K> foo3(f: suspend (T) -> K): Inv2<T, K> = TODO()
fun <I> id(e: I): I = e
fun test(f: (Int) -> String, g: () -> String) {
val a0 = <!INAPPLICABLE_CANDIDATE!>foo1<!>(f)
val a0 = foo1(f)
a0
val a1 = <!INAPPLICABLE_CANDIDATE!>foo2<!>(g)
val a1 = foo2(g)
a1
val a2 = <!INAPPLICABLE_CANDIDATE!>foo3<!>(f)
val a2 = foo3(f)
a2
val a3 = <!INAPPLICABLE_CANDIDATE!>foo1<!>(id(f))
val a3 = foo1(id(f))
a3
val a4 = <!INAPPLICABLE_CANDIDATE!>foo2<!>(id(g))
val a4 = foo2(id(g))
a4
val a5 = <!INAPPLICABLE_CANDIDATE!>foo3<!>(id(f))
val a5 = foo3(id(f))
a5
}
@@ -9,6 +9,6 @@ fun foo(s: SuspendRunnable) {}
fun test(f: () -> Unit) {
foo { }
<!INAPPLICABLE_CANDIDATE!>foo<!>(f)
foo(f)
}
@@ -14,6 +14,6 @@ fun test1() {
// candidate without suspend conversions is more specific
fun test2(f: () -> Int, g: suspend () -> Int) {
foo(f)
<!AMBIGUITY!>foo<!>(f)
foo(g)
}
@@ -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) {
<!INAPPLICABLE_CANDIDATE!>foo<!>(f, f, f)
<!INAPPLICABLE_CANDIDATE!>foo<!>(f, { "str" }, f)
<!INAPPLICABLE_CANDIDATE!>foo<!>(f, f, g)
foo(f, g, g)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
@@ -12,7 +12,7 @@ object Test1 {
fun call(r: SuspendRunnable) {}
fun bar(f: () -> Unit) {
<!DEBUG_INFO_CALL("fqName: Test1.call; typeCall: function")!>call(f)<!>
<!DEBUG_INFO_CALL("fqName: Test1.Scope.call; typeCall: function")!>call(f)<!>
}
}
}
@@ -24,7 +24,7 @@ object Test2 {
fun call(r: SuspendRunnable) {}
fun bar(f: () -> Unit) {
<!DEBUG_INFO_CALL("fqName: Test2.call; typeCall: function")!>call(f)<!>
<!DEBUG_INFO_CALL("fqName: Test2.Scope.call; typeCall: function")!>call(f)<!>
}
}
}
@@ -8,7 +8,7 @@ object Test1 {
fun foo(f: suspend () -> Unit) {}
fun test(g: () -> Unit) {
<!DEBUG_INFO_CALL("fqName: Test1.foo; typeCall: function")!>foo(g)<!>
<!DEBUG_INFO_CALL("fqName: Test1.Scope.foo; typeCall: function")!>foo(g)<!>
}
}
}
@@ -16,9 +16,9 @@ fun test(
foo1 { "str" }
foo1(f0)
<!INAPPLICABLE_CANDIDATE!>foo1<!>(f1)
<!INAPPLICABLE_CANDIDATE!>foo2<!>(f2)
<!INAPPLICABLE_CANDIDATE!>foo3<!>(f3)
foo1(f1)
foo2(f2)
foo3(f3)
foo1(::bar)
@@ -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
) {
<!INAPPLICABLE_CANDIDATE!>useSuspendVararg<!>(sf1, f2, sf3)
}
fun testSuspendConversionInVarargElementsAll(
f1: () -> Unit,
f2: () -> Unit,
f3: () -> Unit
) {
<!INAPPLICABLE_CANDIDATE!>useSuspendVararg<!>(f1, f2, f3)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
@@ -21,7 +21,7 @@ fun foo() {
builder { 1 }
val x = { 1 }
<!INAPPLICABLE_CANDIDATE!>builder<!>(x)
builder(x)
builder({1} as (suspend () -> Int))
var i: Int = 1
@@ -32,7 +32,7 @@ fun foo() {
genericBuilder<Int> { "" }
val y = { 1 }
<!INAPPLICABLE_CANDIDATE!>genericBuilder<!>(y)
genericBuilder(y)
unitBuilder {}
unitBuilder { 1 }
@@ -8,12 +8,12 @@ fun ambiguous(sfn: suspend () -> Unit) = sfn
fun ambiguous(fn: () -> Unit) = fn
fun test1(sfn: suspend () -> Unit) = <!INAPPLICABLE_CANDIDATE!>useFn<!>(sfn)
fun test2(fn: () -> Unit) = <!INAPPLICABLE_CANDIDATE!>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) = <!AMBIGUITY!>ambiguous<!>(fn)
fun test7(): () -> Unit = <!AMBIGUITY!>ambiguous<!> {}
@@ -27,80 +27,208 @@ FILE fqName:<root> fileName:/suspendConversionOnArbitraryExpression.kt
FUN name:testSimple visibility:public modality:FINAL <> (fn:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:kotlin.Function0<kotlin.Unit>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspend>#' type=kotlin.Unit
GET_VAR 'fn: kotlin.Function0<kotlin.Unit> declared in <root>.testSimple' type=kotlin.Function0<kotlin.Unit> origin=null
CALL 'public final fun useSuspend (sfn: kotlin.coroutines.SuspendFunction0<kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
sfn: BLOCK type=kotlin.coroutines.SuspendFunction0<kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Function0<kotlin.Unit> [val]
GET_VAR 'fn: kotlin.Function0<kotlin.Unit> declared in <root>.testSimple' type=kotlin.Function0<kotlin.Unit> origin=null
FUN_EXPR type=kotlin.coroutines.SuspendFunction0<kotlin.Unit> 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<kotlin.Unit> [val] declared in <root>.testSimple' type=kotlin.Function0<kotlin.Unit> origin=null
FUN name:testSimpleNonVal visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspend>#' type=kotlin.Unit
CALL 'public final fun produceFun (): kotlin.Function0<kotlin.Unit> declared in <root>' type=kotlin.Function0<kotlin.Unit> origin=null
CALL 'public final fun useSuspend (sfn: kotlin.coroutines.SuspendFunction0<kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
sfn: BLOCK type=kotlin.coroutines.SuspendFunction0<kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Function0<kotlin.Unit> [val]
CALL 'public final fun produceFun (): kotlin.Function0<kotlin.Unit> declared in <root>' type=kotlin.Function0<kotlin.Unit> origin=null
FUN_EXPR type=kotlin.coroutines.SuspendFunction0<kotlin.Unit> 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<kotlin.Unit> [val] declared in <root>.testSimpleNonVal' type=kotlin.Function0<kotlin.Unit> origin=null
FUN name:testExtAsExt visibility:public modality:FINAL <> (fn:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspendExt>#' type=kotlin.Unit
GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.testExtAsExt' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
CALL 'public final fun useSuspendExt (sfn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<kotlin.Int, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
sfn: BLOCK type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<kotlin.Int, kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> [val]
GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.testExtAsExt' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
FUN_EXPR type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<kotlin.Int, kotlin.Unit> 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<kotlin.Int, kotlin.Unit> [val] declared in <root>.testExtAsExt' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
p1: GET_VAR 'p0: kotlin.Int declared in <root>.testExtAsExt.suspendConversion' type=kotlin.Int origin=null
FUN name:testExtAsSimple visibility:public modality:FINAL <> (fn:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspendArg>#' type=kotlin.Unit
GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.testExtAsSimple' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
CALL 'public final fun useSuspendArg (sfn: kotlin.coroutines.SuspendFunction1<kotlin.Int, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
sfn: BLOCK type=kotlin.coroutines.SuspendFunction1<kotlin.Int, kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> [val]
GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.testExtAsSimple' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
FUN_EXPR type=kotlin.coroutines.SuspendFunction1<kotlin.Int, kotlin.Unit> 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<kotlin.Int, kotlin.Unit> [val] declared in <root>.testExtAsSimple' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
p1: GET_VAR 'p0: kotlin.Int declared in <root>.testExtAsSimple.suspendConversion' type=kotlin.Int origin=null
FUN name:testSimpleAsExt visibility:public modality:FINAL <> (fn:kotlin.Function1<kotlin.Int, kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:kotlin.Function1<kotlin.Int, kotlin.Unit>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspendExt>#' type=kotlin.Unit
GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.testSimpleAsExt' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
CALL 'public final fun useSuspendExt (sfn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<kotlin.Int, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
sfn: BLOCK type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<kotlin.Int, kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Function1<kotlin.Int, kotlin.Unit> [val]
GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.testSimpleAsExt' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
FUN_EXPR type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<kotlin.Int, kotlin.Unit> 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<kotlin.Int, kotlin.Unit> [val] declared in <root>.testSimpleAsExt' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
p1: GET_VAR 'p0: kotlin.Int declared in <root>.testSimpleAsExt.suspendConversion' type=kotlin.Int origin=null
FUN name:testSimpleAsSimpleT visibility:public modality:FINAL <> (fn:kotlin.Function1<kotlin.Int, kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:kotlin.Function1<kotlin.Int, kotlin.Unit>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspendArgT>#' type=kotlin.Unit
GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.testSimpleAsSimpleT' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
CALL 'public final fun useSuspendArgT <T> (sfn: kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendArgT, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
<T>: kotlin.Int
sfn: BLOCK type=kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Function1<kotlin.Int, kotlin.Unit> [val]
GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.testSimpleAsSimpleT' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
FUN_EXPR type=kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION
FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of <root>.useSuspendArgT) returnType:kotlin.Unit [suspend]
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of <root>.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<kotlin.Int, kotlin.Unit> [val] declared in <root>.testSimpleAsSimpleT' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
p1: GET_VAR 'p0: T of <root>.useSuspendArgT declared in <root>.testSimpleAsSimpleT.suspendConversion' type=T of <root>.useSuspendArgT origin=null
FUN name:testSimpleAsExtT visibility:public modality:FINAL <> (fn:kotlin.Function1<kotlin.Int, kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:kotlin.Function1<kotlin.Int, kotlin.Unit>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspendExtT>#' type=kotlin.Unit
GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.testSimpleAsExtT' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
CALL 'public final fun useSuspendExtT <T> (sfn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendExtT, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
<T>: kotlin.Int
sfn: BLOCK type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Function1<kotlin.Int, kotlin.Unit> [val]
GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.testSimpleAsExtT' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
FUN_EXPR type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION
FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of <root>.useSuspendExtT) returnType:kotlin.Unit [suspend]
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of <root>.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<kotlin.Int, kotlin.Unit> [val] declared in <root>.testSimpleAsExtT' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
p1: GET_VAR 'p0: T of <root>.useSuspendExtT declared in <root>.testSimpleAsExtT.suspendConversion' type=T of <root>.useSuspendExtT origin=null
FUN name:testExtAsSimpleT visibility:public modality:FINAL <> (fn:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspendArgT>#' type=kotlin.Unit
GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.testExtAsSimpleT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
CALL 'public final fun useSuspendArgT <T> (sfn: kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendArgT, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
<T>: kotlin.Int
sfn: BLOCK type=kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> [val]
GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.testExtAsSimpleT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
FUN_EXPR type=kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION
FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of <root>.useSuspendArgT) returnType:kotlin.Unit [suspend]
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of <root>.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<kotlin.Int, kotlin.Unit> [val] declared in <root>.testExtAsSimpleT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
p1: GET_VAR 'p0: T of <root>.useSuspendArgT declared in <root>.testExtAsSimpleT.suspendConversion' type=T of <root>.useSuspendArgT origin=null
FUN name:testExtAsExtT visibility:public modality:FINAL <> (fn:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspendExtT>#' type=kotlin.Unit
GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.testExtAsExtT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
CALL 'public final fun useSuspendExtT <T> (sfn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendExtT, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
<T>: kotlin.Int
sfn: BLOCK type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> [val]
GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.testExtAsExtT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
FUN_EXPR type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION
FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of <root>.useSuspendExtT) returnType:kotlin.Unit [suspend]
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of <root>.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<kotlin.Int, kotlin.Unit> [val] declared in <root>.testExtAsExtT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
p1: GET_VAR 'p0: T of <root>.useSuspendExtT declared in <root>.testExtAsExtT.suspendConversion' type=T of <root>.useSuspendExtT origin=null
FUN name:testSimpleSAsSimpleT visibility:public modality:FINAL <S> (fn:kotlin.Function1<S of <root>.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<S of <root>.testSimpleSAsSimpleT, kotlin.Unit>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspendArgT>#' type=kotlin.Unit
GET_VAR 'fn: kotlin.Function1<S of <root>.testSimpleSAsSimpleT, kotlin.Unit> declared in <root>.testSimpleSAsSimpleT' type=kotlin.Function1<S of <root>.testSimpleSAsSimpleT, kotlin.Unit> origin=null
CALL 'public final fun useSuspendArgT <T> (sfn: kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendArgT, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
<T>: S of <root>.testSimpleSAsSimpleT
sfn: BLOCK type=kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:kotlin.Function1<S of <root>.testSimpleSAsSimpleT, kotlin.Unit> [val]
GET_VAR 'fn: kotlin.Function1<S of <root>.testSimpleSAsSimpleT, kotlin.Unit> declared in <root>.testSimpleSAsSimpleT' type=kotlin.Function1<S of <root>.testSimpleSAsSimpleT, kotlin.Unit> origin=null
FUN_EXPR type=kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION
FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of <root>.useSuspendArgT) returnType:kotlin.Unit [suspend]
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of <root>.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<S of <root>.testSimpleSAsSimpleT, kotlin.Unit> [val] declared in <root>.testSimpleSAsSimpleT' type=kotlin.Function1<S of <root>.testSimpleSAsSimpleT, kotlin.Unit> origin=null
p1: GET_VAR 'p0: T of <root>.useSuspendArgT declared in <root>.testSimpleSAsSimpleT.suspendConversion' type=T of <root>.useSuspendArgT origin=null
FUN name:testSimpleSAsExtT visibility:public modality:FINAL <S> (fn:kotlin.Function1<S of <root>.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<S of <root>.testSimpleSAsExtT, kotlin.Unit>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspendExtT>#' type=kotlin.Unit
GET_VAR 'fn: kotlin.Function1<S of <root>.testSimpleSAsExtT, kotlin.Unit> declared in <root>.testSimpleSAsExtT' type=kotlin.Function1<S of <root>.testSimpleSAsExtT, kotlin.Unit> origin=null
CALL 'public final fun useSuspendExtT <T> (sfn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendExtT, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
<T>: S of <root>.testSimpleSAsExtT
sfn: BLOCK type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:kotlin.Function1<S of <root>.testSimpleSAsExtT, kotlin.Unit> [val]
GET_VAR 'fn: kotlin.Function1<S of <root>.testSimpleSAsExtT, kotlin.Unit> declared in <root>.testSimpleSAsExtT' type=kotlin.Function1<S of <root>.testSimpleSAsExtT, kotlin.Unit> origin=null
FUN_EXPR type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION
FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of <root>.useSuspendExtT) returnType:kotlin.Unit [suspend]
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of <root>.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<S of <root>.testSimpleSAsExtT, kotlin.Unit> [val] declared in <root>.testSimpleSAsExtT' type=kotlin.Function1<S of <root>.testSimpleSAsExtT, kotlin.Unit> origin=null
p1: GET_VAR 'p0: T of <root>.useSuspendExtT declared in <root>.testSimpleSAsExtT.suspendConversion' type=T of <root>.useSuspendExtT origin=null
FUN name:testExtSAsSimpleT visibility:public modality:FINAL <S> (fn:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<S of <root>.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<S of <root>.testExtSAsSimpleT, kotlin.Unit>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspendArgT>#' type=kotlin.Unit
GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<S of <root>.testExtSAsSimpleT, kotlin.Unit> declared in <root>.testExtSAsSimpleT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<S of <root>.testExtSAsSimpleT, kotlin.Unit> origin=null
CALL 'public final fun useSuspendArgT <T> (sfn: kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendArgT, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
<T>: S of <root>.testExtSAsSimpleT
sfn: BLOCK type=kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_11 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<S of <root>.testExtSAsSimpleT, kotlin.Unit> [val]
GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<S of <root>.testExtSAsSimpleT, kotlin.Unit> declared in <root>.testExtSAsSimpleT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<S of <root>.testExtSAsSimpleT, kotlin.Unit> origin=null
FUN_EXPR type=kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendArgT, kotlin.Unit> origin=SUSPEND_CONVERSION
FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of <root>.useSuspendArgT) returnType:kotlin.Unit [suspend]
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of <root>.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<S of <root>.testExtSAsSimpleT, kotlin.Unit> [val] declared in <root>.testExtSAsSimpleT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<S of <root>.testExtSAsSimpleT, kotlin.Unit> origin=null
p1: GET_VAR 'p0: T of <root>.useSuspendArgT declared in <root>.testExtSAsSimpleT.suspendConversion' type=T of <root>.useSuspendArgT origin=null
FUN name:testExtSAsExtT visibility:public modality:FINAL <S> (fn:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<S of <root>.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<S of <root>.testExtSAsExtT, kotlin.Unit>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspendExtT>#' type=kotlin.Unit
GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<S of <root>.testExtSAsExtT, kotlin.Unit> declared in <root>.testExtSAsExtT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<S of <root>.testExtSAsExtT, kotlin.Unit> origin=null
CALL 'public final fun useSuspendExtT <T> (sfn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendExtT, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
<T>: S of <root>.testExtSAsExtT
sfn: BLOCK type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_12 type:@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<S of <root>.testExtSAsExtT, kotlin.Unit> [val]
GET_VAR 'fn: @[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<S of <root>.testExtSAsExtT, kotlin.Unit> declared in <root>.testExtSAsExtT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<S of <root>.testExtSAsExtT, kotlin.Unit> origin=null
FUN_EXPR type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<T of <root>.useSuspendExtT, kotlin.Unit> origin=SUSPEND_CONVERSION
FUN ADAPTER_FOR_SUSPEND_CONVERSION name:suspendConversion visibility:local modality:FINAL <> (p0:T of <root>.useSuspendExtT) returnType:kotlin.Unit [suspend]
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_SUSPEND_CONVERSION name:p0 index:0 type:T of <root>.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<S of <root>.testExtSAsExtT, kotlin.Unit> [val] declared in <root>.testExtSAsExtT' type=@[ExtensionFunctionType] @[ExtensionFunctionType] kotlin.Function1<S of <root>.testExtSAsExtT, kotlin.Unit> origin=null
p1: GET_VAR 'p0: T of <root>.useSuspendExtT declared in <root>.testExtSAsExtT.suspendConversion' type=T of <root>.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<kotlin.Unit> origin=CAST typeOperand=kotlin.Function0<kotlin.Unit>
GET_VAR 'a: kotlin.Any declared in <root>.testSmartCastWithSuspendConversion' type=kotlin.Any origin=null
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspend>#' type=kotlin.Unit
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function0<kotlin.Unit>
GET_VAR 'a: kotlin.Any declared in <root>.testSmartCastWithSuspendConversion' type=kotlin.Any origin=null
CALL 'public final fun useSuspend (sfn: kotlin.coroutines.SuspendFunction0<kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
sfn: BLOCK type=kotlin.coroutines.SuspendFunction0<kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_13 type:kotlin.Function0<kotlin.Unit> [val]
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function0<kotlin.Unit>
GET_VAR 'a: kotlin.Any declared in <root>.testSmartCastWithSuspendConversion' type=kotlin.Any origin=null
FUN_EXPR type=kotlin.coroutines.SuspendFunction0<kotlin.Unit> 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<kotlin.Unit> [val] declared in <root>.testSmartCastWithSuspendConversion' type=kotlin.Function0<kotlin.Unit> 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:<root> fileName:/suspendConversionOnArbitraryExpression.kt
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=CAST typeOperand=kotlin.Function0<kotlin.Unit>
GET_VAR 'var b: kotlin.Any [var] declared in <root>.testSmartCastOnVarWithSuspendConversion' type=kotlin.Any origin=null
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /useSuspend>#' type=kotlin.Unit
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function0<kotlin.Unit>
GET_VAR 'var b: kotlin.Any [var] declared in <root>.testSmartCastOnVarWithSuspendConversion' type=kotlin.Any origin=null
CALL 'public final fun useSuspend (sfn: kotlin.coroutines.SuspendFunction0<kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
sfn: BLOCK type=kotlin.coroutines.SuspendFunction0<kotlin.Unit> origin=SUSPEND_CONVERSION
VAR IR_TEMPORARY_VARIABLE name:tmp_14 type:kotlin.Function0<kotlin.Unit> [val]
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function0<kotlin.Unit>
GET_VAR 'var b: kotlin.Any [var] declared in <root>.testSmartCastOnVarWithSuspendConversion' type=kotlin.Any origin=null
FUN_EXPR type=kotlin.coroutines.SuspendFunction0<kotlin.Unit> 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<kotlin.Unit> [val] declared in <root>.testSmartCastOnVarWithSuspendConversion' type=kotlin.Function0<kotlin.Unit> origin=null
FUN name:testSmartCastVsSuspendConversion visibility:public modality:FINAL <> (a:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit>
BLOCK_BODY