FIR: keep captured types in substitution scope

This commit is contained in:
Mikhail Glukhikh
2020-09-17 14:03:04 +03:00
parent b7059a3eeb
commit b64b32e06b
19 changed files with 64 additions and 69 deletions
@@ -191,7 +191,7 @@ digraph complex_kt {
color=blue
56 [label="Enter block"];
57 [label="Access variable this@R|/firstIsInstanceOrNull|"];
58 [label="Function call: this@R|/firstIsInstanceOrNull|.R|FakeOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<kotlin/Any?>|>|()"];
58 [label="Function call: this@R|/firstIsInstanceOrNull|.R|FakeOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<CapturedType(*)>|>|()"];
59 [label="Variable declaration: lval <iterator>: R|kotlin/collections/Iterator<kotlin/Any?>|"];
subgraph cluster_20 {
color=blue
@@ -25,7 +25,7 @@ FILE: complex.kt
}
public final inline fun <reified T : R|kotlin/Any|> R|kotlin/collections/List<*>|.firstIsInstanceOrNull(): R|T?| {
lval <iterator>: R|kotlin/collections/Iterator<kotlin/Any?>| = this@R|/firstIsInstanceOrNull|.R|FakeOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<kotlin/Any?>|>|()
lval <iterator>: R|kotlin/collections/Iterator<kotlin/Any?>| = this@R|/firstIsInstanceOrNull|.R|FakeOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<CapturedType(*)>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
lval element: R|kotlin/Any?| = R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|kotlin/Any?|>|()
when () {
@@ -25,8 +25,8 @@ digraph flowFromInplaceLambda_kt {
5 [label="Enter block"];
6 [label="Access variable R|<local>/x|"];
7 [label="Const: Int(0)"];
8 [label="Function call: R|<local>/x|.R|FakeOverride<kotlin/Array.get: R|K|>|(...)"];
9 [label="Jump: ^select R|<local>/x|.R|FakeOverride<kotlin/Array.get: R|K|>|(Int(0))"];
8 [label="Function call: R|<local>/x|.R|FakeOverride<kotlin/Array.get: R|CapturedType(out K)|>|(...)"];
9 [label="Jump: ^select R|<local>/x|.R|FakeOverride<kotlin/Array.get: R|CapturedType(out K)|>|(Int(0))"];
10 [label="Stub" style="filled" fillcolor=gray];
11 [label="Exit block" style="filled" fillcolor=gray];
}
@@ -2,7 +2,7 @@ FILE: flowFromInplaceLambda.kt
public final fun takeInt(x: R|kotlin/Int|): R|kotlin/Unit| {
}
public final fun <K> select(vararg x: R|kotlin/Array<out K>|): R|K| {
^select R|<local>/x|.R|FakeOverride<kotlin/Array.get: R|K|>|(Int(0))
^select R|<local>/x|.R|FakeOverride<kotlin/Array.get: R|CapturedType(out K)|>|(Int(0))
}
public final fun <T> id(x: R|T|): R|T| {
^id R|<local>/x|
@@ -24,6 +24,6 @@ FILE: test.kt
R|<local>/resolvedDescriptor|.R|/foo|()
}
public final fun otherTest(call: R|Call<*>|, resolvedCall: R|ResolvedCall<*>|): R|kotlin/Unit| {
R|<local>/call|.R|FakeOverride</Call.resultingDescriptor: R|Descriptor|>|.R|/name|
R|<local>/call|.R|FakeOverride</Call.resultingDescriptor: R|CapturedType(*)|>|.R|/name|
R|<local>/resolvedCall|.R|/ResolvedCall.resultingDescriptor|.R|/name|
}
@@ -13,7 +13,7 @@ FILE: nestedExtensionFunctionType.kt
}
public final fun test_2(a: R|A|, vararg zs: @R|kotlin/ExtensionFunctionType|() R|kotlin/Array<out kotlin/Function1<A, kotlin/Unit>>|): R|kotlin/Unit| {
lval <iterator>: R|kotlin/collections/Iterator<kotlin/Function1<A, kotlin/Unit>>| = R|<local>/zs|.R|FakeOverride<kotlin/Array.iterator: R|kotlin/collections/Iterator<kotlin/Function1<A, kotlin/Unit>>|>|()
lval <iterator>: R|kotlin/collections/Iterator<kotlin/Function1<A, kotlin/Unit>>| = R|<local>/zs|.R|FakeOverride<kotlin/Array.iterator: R|kotlin/collections/Iterator<CapturedType(out kotlin/Function1<A, kotlin/Unit>)>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
lval z: R|(A) -> kotlin/Unit| = R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|(A) -> kotlin/Unit|>|()
R|<local>/z|.R|FakeOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(R|<local>/a|)
@@ -19,9 +19,9 @@ FILE: simpleCapturedTypes.kt
^ this@R|/idP|
}
private final fun getSetterInfos(kc: R|KC<out Ann>|): R|kotlin/Unit| {
R|/id|<R|Ann|>(R|<local>/kc|).R|FakeOverride</KC.x: R|Ann|>|.R|/Ann.foo|()
R|<local>/kc|.R|/idR|<R|Ann|>().R|FakeOverride</KC.x: R|Ann|>|.R|/Ann.foo|()
R|<local>/kc|.R|/idP|<R|Ann|>.R|FakeOverride</KC.x: R|Ann|>|.R|/Ann.foo|()
R|/id|<R|Ann|>(R|<local>/kc|).R|FakeOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|()
R|<local>/kc|.R|/idR|<R|Ann|>().R|FakeOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|()
R|<local>/kc|.R|/idP|<R|Ann|>.R|FakeOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|()
lval x1: R|KC<out Ann>| = R|/id|<R|Ann|>(R|<local>/kc|)
lval x2: R|KC<out Ann>| = R|<local>/kc|.R|/idR|<R|Ann|>()
lval x3: R|KC<out Ann>| = R|<local>/kc|.R|/idP|<R|Ann|>
@@ -35,8 +35,8 @@ FILE: referenceToExtension.kt
}
public final fun test_1(): R|kotlin/Unit| {
lval memberValRef: R|kotlin/reflect/KProperty1<GenericTest.B<*>, GenericTest.A<out kotlin/Any?>>| = Q|GenericTest.B|::R|FakeOverride</GenericTest.B.memberVal: R|GenericTest.A<out kotlin/Any?>|>|
lval memberFunRef: R|kotlin/reflect/KFunction1<GenericTest.B<*>, GenericTest.A<out kotlin/Any?>>| = Q|GenericTest.B|::R|FakeOverride</GenericTest.B.memberFun: R|GenericTest.A<out kotlin/Any?>|>|
lval memberValRef: R|kotlin/reflect/KProperty1<GenericTest.B<*>, GenericTest.A<CapturedType(*)>>| = Q|GenericTest.B|::R|FakeOverride</GenericTest.B.memberVal: R|GenericTest.A<CapturedType(*)>|>|
lval memberFunRef: R|kotlin/reflect/KFunction1<GenericTest.B<*>, GenericTest.A<CapturedType(*)>>| = Q|GenericTest.B|::R|FakeOverride</GenericTest.B.memberFun: R|GenericTest.A<CapturedType(*)>|>|
}
public final fun test_2(): R|kotlin/Unit| {
@@ -73,12 +73,12 @@ FILE: typeAliasWithTypeArguments.kt
public final fun test_6(a: R|A|, out1: R|Out1<A>|, out2: R|Out1<in A>|, out3: R|Out1<out A>|): R|kotlin/Unit| {
R|<local>/out1|.R|FakeOverride</Out.value: R|A|>|().R|/A.foo|()
R|<local>/out2|.<Unresolved name: value>#().<Unresolved name: foo>#()
R|<local>/out3|.R|FakeOverride</Out.value: R|A|>|().R|/A.foo|()
R|<local>/out3|.R|FakeOverride</Out.value: R|CapturedType(out A)|>|().R|/A.foo|()
}
public final fun test_7(a: R|A|, inv1: R|Invariant1<A>|, inv2: R|Invariant1<in A>|, inv3: R|Invariant1<out A>|): R|kotlin/Unit| {
R|<local>/inv1|.R|FakeOverride</Invariant.value: R|A|>|().R|/A.foo|()
R|<local>/inv2|.R|FakeOverride</Invariant.value: R|kotlin/Any?|>|().<Unresolved name: foo>#()
R|<local>/inv3|.R|FakeOverride</Invariant.value: R|A|>|().R|/A.foo|()
R|<local>/inv2|.R|FakeOverride</Invariant.value: R|CapturedType(in A)|>|().<Unresolved name: foo>#()
R|<local>/inv3|.R|FakeOverride</Invariant.value: R|CapturedType(out A)|>|().R|/A.foo|()
R|<local>/inv1|.R|FakeOverride</Invariant.take: R|kotlin/Unit|>|(R|<local>/a|)
R|<local>/inv2|.R|FakeOverride</Invariant.take: R|kotlin/Unit|>|(R|<local>/a|)
R|<local>/inv3|.<Inapplicable(INAPPLICABLE): /Invariant.take>#(R|<local>/a|)
@@ -9,7 +9,7 @@ FILE: varargInPrimaryConstructor.kt
}
public final fun test_1(foo: R|Foo|): R|kotlin/Unit| {
lval <iterator>: R|kotlin/collections/Iterator<kotlin/String>| = R|<local>/foo|.R|/Foo.strings|.R|FakeOverride<kotlin/Array.iterator: R|kotlin/collections/Iterator<kotlin/String>|>|()
lval <iterator>: R|kotlin/collections/Iterator<kotlin/String>| = R|<local>/foo|.R|/Foo.strings|.R|FakeOverride<kotlin/Array.iterator: R|kotlin/collections/Iterator<CapturedType(out kotlin/String)>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
lval s: R|kotlin/String| = R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|kotlin/String|>|()
R|<local>/s|.R|kotlin/String.length|
@@ -17,7 +17,7 @@ FILE: varargInPrimaryConstructor.kt
}
public final fun test_2(vararg strings: R|kotlin/Array<out kotlin/String>|): R|kotlin/Unit| {
lval <iterator>: R|kotlin/collections/Iterator<kotlin/String>| = R|<local>/strings|.R|FakeOverride<kotlin/Array.iterator: R|kotlin/collections/Iterator<kotlin/String>|>|()
lval <iterator>: R|kotlin/collections/Iterator<kotlin/String>| = R|<local>/strings|.R|FakeOverride<kotlin/Array.iterator: R|kotlin/collections/Iterator<CapturedType(out kotlin/String)>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
lval s: R|kotlin/String| = R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|kotlin/String|>|()
R|<local>/s|.R|kotlin/String.length|
@@ -13,7 +13,7 @@ FILE: arrayFirstOrNull.kt
Null(null)
}
else -> {
this@R|/firstOrNullX|.R|FakeOverride<kotlin/Array.get: R|T|>|(Int(0))
this@R|/firstOrNullX|.R|FakeOverride<kotlin/Array.get: R|CapturedType(out T)|>|(Int(0))
}
}
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusIm
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.chain
@@ -29,7 +28,6 @@ import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
class FirClassSubstitutionScope(
private val session: FirSession,
@@ -130,18 +128,6 @@ class FirClassSubstitutionScope(
return substitutor.substituteOrNull(this)
}
private fun ConeKotlinType.approximateCapturedCovariant(): ConeKotlinType {
return session.inferenceComponents.approximator.approximateToSuperType(
this, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
) as? ConeKotlinType ?: this
}
private fun ConeKotlinType.approximateCapturedContravariant(): ConeKotlinType {
return session.inferenceComponents.approximator.approximateToSubType(
this, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
) as? ConeKotlinType ?: this
}
private fun createFakeOverrideFunction(original: FirFunctionSymbol<*>): FirFunctionSymbol<*> {
if (substitutor == ConeSubstitutor.Empty) return original
val member = when (original) {
@@ -153,7 +139,7 @@ class FirClassSubstitutionScope(
val (newTypeParameters, newReceiverType, newReturnType, newSubstitutor) = createSubstitutedData(member)
val newParameterTypes = member.valueParameters.map {
it.returnTypeRef.coneType.substitute(newSubstitutor)?.approximateCapturedContravariant()
it.returnTypeRef.coneType.substitute(newSubstitutor)
}
if (newReceiverType == null && newReturnType == null && newParameterTypes.all { it == null } &&
@@ -185,7 +171,7 @@ class FirClassSubstitutionScope(
val (newTypeParameters, _, newReturnType, newSubstitutor) = createSubstitutedData(constructor)
val newParameterTypes = constructor.valueParameters.map {
it.returnTypeRef.coneType.substitute(newSubstitutor)?.approximateCapturedContravariant()
it.returnTypeRef.coneType.substitute(newSubstitutor)
}
if (newReturnType == null && newParameterTypes.all { it == null } && newTypeParameters === constructor.typeParameters) {
@@ -237,10 +223,10 @@ class FirClassSubstitutionScope(
)
val receiverType = member.receiverTypeRef?.coneType
val newReceiverType = receiverType?.substitute(substitutor)?.approximateCapturedContravariant()
val newReceiverType = receiverType?.substitute(substitutor)
val returnType = typeCalculator.tryCalculateReturnType(member).type
val newReturnType = returnType.substitute(substitutor)?.approximateCapturedCovariant()
val newReturnType = returnType.substitute(substitutor)
return SubstitutedData(newTypeParameters, newReceiverType, newReturnType, substitutor)
}
@@ -250,7 +236,7 @@ class FirClassSubstitutionScope(
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
val returnType = typeCalculator.tryCalculateReturnType(member).type
val newReturnType = returnType.substitute()?.approximateCapturedCovariant() ?: return original
val newReturnType = returnType.substitute() ?: return original
return createFakeOverrideField(session, member, original, newReturnType, derivedClassId)
}
@@ -261,10 +247,10 @@ class FirClassSubstitutionScope(
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
val returnType = typeCalculator.tryCalculateReturnType(member).type
val newReturnType = returnType.substitute()?.approximateCapturedCovariant()
val newReturnType = returnType.substitute()
val newParameterTypes = member.getter.valueParameters.map {
it.returnTypeRef.coneType.substitute()?.approximateCapturedContravariant()
it.returnTypeRef.coneType.substitute()
}
if (newReturnType == null && newParameterTypes.all { it == null }) {
@@ -1,5 +1,4 @@
// !LANGUAGE: -NewInference
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// FILE: example/Hello.java
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// FILE: example/Hello.java
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// FILE: A.java
public class A<T> {
@@ -1,7 +1,7 @@
// JAVAC_EXPECTED_FILE
// FILE: KotlinFile.kt
fun foo(javaClass: JavaClass<String>): String {
return javaClass.doSomething("", 1) { s: String -> "" }
return javaClass.<!INAPPLICABLE_CANDIDATE!>doSomething<!>("", 1) { s: String -> "" }
}
// FILE: JavaClass.java
@@ -2,7 +2,7 @@
// FILE: KotlinFile.kt
fun foo(javaClass: JavaClass<Int>) {
val a: String = javaClass.<!INAPPLICABLE_CANDIDATE!>doSomething1<!>("", 1) { p: String -> p }
val b: String = javaClass.doSomething2("", 1, true) { p: Int -> p }
val b: String = javaClass.<!INAPPLICABLE_CANDIDATE!>doSomething2<!>("", 1, true) { p: Int -> p }
}
// FILE: JavaClass.java
@@ -2,21 +2,30 @@ FILE fqName:<root> fileName:/genericSamProjectedOut.kt
FUN name:test visibility:public modality:FINAL <> (a:example.SomeJavaClass<out kotlin.String>) returnType:kotlin.Unit
VALUE_PARAMETER name:a index:0 type:example.SomeJavaClass<out kotlin.String>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): example/SomeJavaClass.someFunction>#' type=kotlin.Unit
FUN_EXPR type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Unit declared in <root>.test'
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): example/SomeJavaClass.plus>#' type=kotlin.Unit
FUN_EXPR type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Unit declared in <root>.test'
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): example/SomeJavaClass.get>#' type=kotlin.Unit
FUN_EXPR type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Unit declared in <root>.test'
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
CALL 'public open fun someFunction (hello: example.Hello<A of example.SomeJavaClass?>?): kotlin.Unit declared in example.SomeJavaClass' type=kotlin.Unit origin=null
$this: GET_VAR 'a: example.SomeJavaClass<out kotlin.String> declared in <root>.test' type=example.SomeJavaClass<out kotlin.String> origin=null
hello: TYPE_OP type=example.Hello<kotlin.Any?>? origin=SAM_CONVERSION typeOperand=example.Hello<kotlin.Any?>?
FUN_EXPR type=kotlin.Function1<kotlin.String?, kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:kotlin.String?) returnType:kotlin.Unit
VALUE_PARAMETER name:it index:0 type:kotlin.String?
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (it: kotlin.String?): kotlin.Unit declared in <root>.test'
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
CALL 'public open fun plus (hello: example.Hello<A of example.SomeJavaClass?>?): kotlin.Unit [operator] declared in example.SomeJavaClass' type=kotlin.Unit origin=PLUS
$this: GET_VAR 'a: example.SomeJavaClass<out kotlin.String> declared in <root>.test' type=example.SomeJavaClass<out kotlin.String> origin=null
hello: TYPE_OP type=example.Hello<kotlin.Any?>? origin=SAM_CONVERSION typeOperand=example.Hello<kotlin.Any?>?
FUN_EXPR type=kotlin.Function1<kotlin.String?, kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:kotlin.String?) returnType:kotlin.Unit
VALUE_PARAMETER name:it index:0 type:kotlin.String?
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (it: kotlin.String?): kotlin.Unit declared in <root>.test'
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
CALL 'public open fun get (hello: example.Hello<A of example.SomeJavaClass?>?): kotlin.Unit [operator] declared in example.SomeJavaClass' type=kotlin.Unit origin=null
$this: GET_VAR 'a: example.SomeJavaClass<out kotlin.String> declared in <root>.test' type=example.SomeJavaClass<out kotlin.String> origin=null
hello: TYPE_OP type=example.Hello<kotlin.Any?>? origin=SAM_CONVERSION typeOperand=example.Hello<kotlin.Any?>?
FUN_EXPR type=kotlin.Function1<kotlin.String?, kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:kotlin.String?) returnType:kotlin.Unit
VALUE_PARAMETER name:it index:0 type:kotlin.String?
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (it: kotlin.String?): kotlin.Unit declared in <root>.test'
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
@@ -7,12 +7,15 @@ FILE fqName:<root> fileName:/genericSamSmartcast.kt
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=<root>.A<*>
GET_VAR 'x: kotlin.Any declared in <root>.f' type=kotlin.Any origin=null
then: RETURN type=kotlin.Nothing from='public final fun f (x: kotlin.Any): kotlin.String declared in <root>'
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): /A.call>#' type=kotlin.String?
FUN_EXPR type=kotlin.Function1<kotlin.Any?, kotlin.String> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (y:kotlin.Any?) returnType:kotlin.String
VALUE_PARAMETER name:y index:0 type:kotlin.Any?
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (y: kotlin.Any?): kotlin.String declared in <root>.f'
CONST String type=kotlin.String value="OK"
CALL 'public open fun call (block: <root>.A.I<T of <root>.A?>?): kotlin.String? declared in <root>.A' type=kotlin.String? origin=null
$this: TYPE_OP type=<root>.A<*> origin=IMPLICIT_CAST typeOperand=<root>.A<*>
GET_VAR 'x: kotlin.Any declared in <root>.f' type=kotlin.Any origin=null
block: TYPE_OP type=<root>.A.I<kotlin.Any?>? origin=SAM_CONVERSION typeOperand=<root>.A.I<kotlin.Any?>?
FUN_EXPR type=kotlin.Function1<kotlin.Any?, kotlin.String?> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (y:kotlin.Any?) returnType:kotlin.String?
VALUE_PARAMETER name:y index:0 type:kotlin.Any?
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (y: kotlin.Any?): kotlin.String? declared in <root>.f'
CONST String type=kotlin.String value="OK"
RETURN type=kotlin.Nothing from='public final fun f (x: kotlin.Any): kotlin.String declared in <root>'
CONST String type=kotlin.String value="Fail"