[FIR] Insert SAM conversion expressions during completion

#KT-62847 Fixed
This commit is contained in:
Kirill Rakhman
2023-11-15 12:24:31 +01:00
committed by Space Team
parent 0b28e770b2
commit dd1d36816b
68 changed files with 611 additions and 268 deletions
@@ -4,10 +4,10 @@ FIR source kind: KtRealSourceElementKind
FIR element rendered:
public final [ResolvedTo(BODY_RESOLVE)] fun resolveMe(): R|kotlin/Unit| {
R|foo/testMe|(<L> = [ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=@R|foo/Anno|(<strcat>(String(testMe param type ), constant#)) foo/Foo] testMe@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] b: R|@R|foo/Anno|(position = <strcat>(String(foo param type ), R|foo/constant|)) foo/Arg|): R|@R|foo/Anno|(position = <strcat>(String(foo return type ), R|foo/constant|)) foo/Arg| <inline=NoInline> {
R|foo/testMe|(<L> = SAM([ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=@R|foo/Anno|(<strcat>(String(testMe param type ), constant#)) foo/Foo] testMe@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] b: R|@R|foo/Anno|(position = <strcat>(String(foo param type ), R|foo/constant|)) foo/Arg|): R|@R|foo/Anno|(position = <strcat>(String(foo return type ), R|foo/constant|)) foo/Arg| <inline=NoInline> {
^ R|<local>/b|
}
)
))
}
FIR FILE:
@@ -38,8 +38,8 @@ FILE: [ResolvedTo(IMPORTS)] lambdaAsSAMInterfaceWithAnnotation.kt
public final [ResolvedTo(CONTRACTS)] fun testMe([ResolvedTo(CONTRACTS)] f: R|@R|foo/Anno|(<strcat>(String(testMe param type ), constant#)) foo/Foo|): R|kotlin/Unit| {
}
public final [ResolvedTo(BODY_RESOLVE)] fun resolveMe(): R|kotlin/Unit| {
R|foo/testMe|(<L> = [ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=@R|foo/Anno|(<strcat>(String(testMe param type ), constant#)) foo/Foo] testMe@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] b: R|@R|foo/Anno|(position = <strcat>(String(foo param type ), R|foo/constant|)) foo/Arg|): R|@R|foo/Anno|(position = <strcat>(String(foo return type ), R|foo/constant|)) foo/Arg| <inline=NoInline> {
R|foo/testMe|(<L> = SAM([ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=@R|foo/Anno|(<strcat>(String(testMe param type ), constant#)) foo/Foo] testMe@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] b: R|@R|foo/Anno|(position = <strcat>(String(foo param type ), R|foo/constant|)) foo/Arg|): R|@R|foo/Anno|(position = <strcat>(String(foo return type ), R|foo/constant|)) foo/Arg| <inline=NoInline> {
^ R|<local>/b|
}
)
}
))
}
@@ -193,10 +193,10 @@ FILE: [ResolvedTo(IMPORTS)] lambdaAsSAMInterface.kt
public final [ResolvedTo(CONTRACTS)] fun testMe([ResolvedTo(CONTRACTS)] f: R|foo/Foo|): R|kotlin/Unit| {
}
public final [ResolvedTo(BODY_RESOLVE)] fun resolveMe(): R|kotlin/Unit| {
R|foo/testMe|(<L> = [ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=foo/Foo] testMe@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] b: R|foo/Arg|): R|foo/Arg| <inline=NoInline> {
R|foo/testMe|(<L> = SAM([ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=foo/Foo] testMe@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] b: R|foo/Arg|): R|foo/Arg| <inline=NoInline> {
^ R|<local>/b|
}
)
))
}
FILE RAW TO BODY:
@@ -214,8 +214,8 @@ FILE: [ResolvedTo(BODY_RESOLVE)] lambdaAsSAMInterface.kt
public final [ResolvedTo(BODY_RESOLVE)] fun testMe([ResolvedTo(BODY_RESOLVE)] f: R|foo/Foo|): R|kotlin/Unit| {
}
public final [ResolvedTo(BODY_RESOLVE)] fun resolveMe(): R|kotlin/Unit| {
R|foo/testMe|(<L> = [ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=foo/Foo] testMe@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] b: R|foo/Arg|): R|foo/Arg| <inline=NoInline> {
R|foo/testMe|(<L> = SAM([ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=foo/Foo] testMe@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] b: R|foo/Arg|): R|foo/Arg| <inline=NoInline> {
^ R|<local>/b|
}
)
))
}
@@ -288,10 +288,10 @@ FILE: [ResolvedTo(IMPORTS)] lambdaAsSAMInterfaceScript.kts
}
public final [ResolvedTo(BODY_RESOLVE)] fun resolveMe(): R|kotlin/Unit| {
R|foo/testMe|(<L> = [ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=foo/Foo] testMe@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] b: R|foo/Arg|): R|foo/Arg| <inline=NoInline> {
R|foo/testMe|(<L> = SAM([ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=foo/Foo] testMe@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] b: R|foo/Arg|): R|foo/Arg| <inline=NoInline> {
^ R|<local>/b|
}
)
))
}
@@ -317,8 +317,9 @@ FILE: [ResolvedTo(BODY_RESOLVE)] lambdaAsSAMInterfaceScript.kts
}
public final [ResolvedTo(BODY_RESOLVE)] fun resolveMe(): R|kotlin/Unit| {
R|foo/testMe|(<L> = [ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=foo/Foo] testMe@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] b: R|foo/Arg|): R|foo/Arg| <inline=NoInline> {
R|foo/testMe|(<L> = SAM([ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=foo/Foo] testMe@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] b: R|foo/Arg|): R|foo/Arg| <inline=NoInline> {
^ R|<local>/b|
}
)
))
}
@@ -50352,6 +50352,12 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo
runTest("compiler/testData/codegen/box/sam/kt59858.kt");
}
@Test
@TestMetadata("noConversionFromSamToSam.kt")
public void testNoConversionFromSamToSam() throws Exception {
runTest("compiler/testData/codegen/box/sam/noConversionFromSamToSam.kt");
}
@Test
@TestMetadata("nonInlinedSamWrapper.kt")
public void testNonInlinedSamWrapper() throws Exception {
@@ -50352,6 +50352,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
runTest("compiler/testData/codegen/box/sam/kt59858.kt");
}
@Test
@TestMetadata("noConversionFromSamToSam.kt")
public void testNoConversionFromSamToSam() throws Exception {
runTest("compiler/testData/codegen/box/sam/noConversionFromSamToSam.kt");
}
@Test
@TestMetadata("nonInlinedSamWrapper.kt")
public void testNonInlinedSamWrapper() throws Exception {
@@ -1,7 +1,7 @@
FILE: javaCollector.kt
public final fun foo(): R|kotlin/Unit| {
R|kotlin/collections/listOf|<R|kotlin/String|>(String()).R|SubstitutionOverride<kotlin/collections/List.stream: R|@EnhancedNullability java/util/stream/Stream<@EnhancedNullability kotlin/String>|>|().R|SubstitutionOverride<java/util/stream/Stream.collect: R|ft<R & Any, R?>|>|<R|ft<kotlin/collections/MutableMap<kotlin/String!, kotlin/Int!>, kotlin/collections/Map<kotlin/String!, kotlin/Int!>?>|, R|ft<CapturedType(*), CapturedType(*)?>|>(Q|java/util/stream/Collectors|.R|java/util/stream/Collectors.groupingBy*s|<R|kotlin/String!|, R|kotlin/String!|, R|ft<CapturedType(*), CapturedType(*)?>|, R|kotlin/Int!|>(groupingBy@fun <anonymous>(it: R|@EnhancedNullability kotlin/String!|): R|@EnhancedNullability kotlin/String!| <inline=NoInline> {
R|kotlin/collections/listOf|<R|kotlin/String|>(String()).R|SubstitutionOverride<kotlin/collections/List.stream: R|@EnhancedNullability java/util/stream/Stream<@EnhancedNullability kotlin/String>|>|().R|SubstitutionOverride<java/util/stream/Stream.collect: R|ft<R & Any, R?>|>|<R|ft<kotlin/collections/MutableMap<kotlin/String!, kotlin/Int!>, kotlin/collections/Map<kotlin/String!, kotlin/Int!>?>|, R|ft<CapturedType(*), CapturedType(*)?>|>(Q|java/util/stream/Collectors|.R|java/util/stream/Collectors.groupingBy*s|<R|kotlin/String!|, R|kotlin/String!|, R|ft<CapturedType(*), CapturedType(*)?>|, R|kotlin/Int!|>(SAM(groupingBy@fun <anonymous>(it: R|@EnhancedNullability kotlin/String!|): R|@EnhancedNullability kotlin/String!| <inline=NoInline> {
^ R|<local>/it|
}
, Q|java/util/stream/Collectors|.R|java/util/stream/Collectors.collectingAndThen*s|<R|kotlin/String!|, R|ft<CapturedType(*), CapturedType(*)?>|, R|kotlin/Long!|, R|kotlin/Int!|>(Q|java/util/stream/Collectors|.R|java/util/stream/Collectors.counting*s|<R|kotlin/String|>(), Q|kotlin/Long|::R|kotlin/Long.toInt|)))
), Q|java/util/stream/Collectors|.R|java/util/stream/Collectors.collectingAndThen*s|<R|kotlin/String!|, R|ft<CapturedType(*), CapturedType(*)?>|, R|kotlin/Long!|, R|kotlin/Int!|>(Q|java/util/stream/Collectors|.R|java/util/stream/Collectors.counting*s|<R|kotlin/String|>(), SAM(Q|kotlin/Long|::R|kotlin/Long.toInt|))))
}
@@ -1,7 +1,7 @@
FILE: main.kt
public final fun foo(): R|kotlin/Unit| {
Q|RawType|.R|/RawType.bar*s|(<L> = bar@fun <anonymous>(it: R|kotlin/CharSequence!|): R|kotlin/Boolean| <inline=NoInline> {
Q|RawType|.R|/RawType.bar*s|(<L> = SAM(bar@fun <anonymous>(it: R|kotlin/CharSequence!|): R|kotlin/Boolean| <inline=NoInline> {
^ CMP(>, R|<local>/it|.R|kotlin/CharSequence.length|.R|kotlin/Int.compareTo|(Int(0)))
}
)
))
}
@@ -1,23 +1,23 @@
FILE: main.kt
public final fun main(): R|kotlin/Unit| {
Q|JavaUsage|.R|/JavaUsage.foo1*s|(<L> = foo1@fun <anonymous>(x: R|kotlin/Int!|): R|kotlin/String!| <inline=NoInline> {
Q|JavaUsage|.R|/JavaUsage.foo1*s|(<L> = SAM(foo1@fun <anonymous>(x: R|kotlin/Int!|): R|kotlin/String!| <inline=NoInline> {
^ R|<local>/x|.R|kotlin/Int.toInt|().R|kotlin/Int.toString|()
}
)
Q|JavaUsage|.R|/JavaUsage.foo2*s|(<L> = foo2@fun <anonymous>(x: R|kotlin/Number!|): R|kotlin/CharSequence!| <inline=NoInline> {
))
Q|JavaUsage|.R|/JavaUsage.foo2*s|(<L> = SAM(foo2@fun <anonymous>(x: R|kotlin/Number!|): R|kotlin/CharSequence!| <inline=NoInline> {
^ R|<local>/x|.R|kotlin/Number.toInt|().R|kotlin/Int.toString|()
}
)
))
Q|JavaUsage|.R|/JavaUsage.foo2*s<Inapplicable(INAPPLICABLE): /JavaUsage.foo2>#|(<L> = foo2@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/CharSequence!| <inline=Unknown> {
^ R|<local>/x|.R|kotlin/Int.toString|()
}
)
Q|JavaUsage|.R|/JavaUsage.foo3*s|<R|kotlin/Int!|, R|kotlin/String!|>(foo3@fun <anonymous>(x: R|kotlin/Int!|): R|kotlin/String!| <inline=NoInline> {
Q|JavaUsage|.R|/JavaUsage.foo3*s|<R|kotlin/Int!|, R|kotlin/String!|>(SAM(foo3@fun <anonymous>(x: R|kotlin/Int!|): R|kotlin/String!| <inline=NoInline> {
^ R|<local>/x|.R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.toString|()
}
, Int(1))
Q|JavaUsage|.R|/JavaUsage.foo3*s|<R|kotlin/Int!|, R|kotlin/String!|>(foo3@fun <anonymous>(x: R|kotlin/Number|): R|kotlin/String!| <inline=NoInline> {
), Int(1))
Q|JavaUsage|.R|/JavaUsage.foo3*s|<R|kotlin/Int!|, R|kotlin/String!|>(SAM(foo3@fun <anonymous>(x: R|kotlin/Number|): R|kotlin/String!| <inline=NoInline> {
^ R|<local>/x|.R|kotlin/Number.toInt|().R|kotlin/Int.toString|()
}
, Int(2))
), Int(2))
}
@@ -33,11 +33,11 @@ FILE: kotlinSam.kt
^ CMP(>, R|<local>/t|.R|kotlin/Int.compareTo|(Int(1)))
}
R|/foo1|(<L> = foo1@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| <inline=NoInline> {
R|/foo1|(<L> = SAM(foo1@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| <inline=NoInline> {
^ CMP(>, R|<local>/x|.R|kotlin/Int.compareTo|(Int(1)))
}
)
R|/foo1|(R|<local>/f|)
))
R|/foo1|(SAM(R|<local>/f|))
R|/foo2<Inapplicable(INAPPLICABLE): /foo2>#|(<L> = foo2@fun <anonymous>(x: R|kotlin/Nothing|): R|kotlin/Boolean| <inline=Unknown> {
^ CMP(>, R|<local>/x|.<Unresolved name: compareTo>#(Int(1)))
}
@@ -48,9 +48,9 @@ FILE: kotlinSam.kt
}
)
R|/foo3<Inapplicable(INAPPLICABLE): /foo3>#|(R|<local>/f|)
R|/foo4|(<L> = foo4@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| <inline=NoInline> {
R|/foo4|(<L> = SAM(foo4@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| <inline=NoInline> {
^ CMP(>, R|<local>/x|.R|kotlin/Int.compareTo|(Int(1)))
}
)
R|/foo4|(R|<local>/f|)
))
R|/foo4|(SAM(R|<local>/f|))
}
@@ -1,7 +1,7 @@
FILE: main.kt
public final fun test(x: R|A<*>|): R|kotlin/Unit| {
R|<local>/x|.R|SubstitutionOverride</A.call: R|kotlin/Unit|>|(vararg(call@fun <anonymous>(y: R|kotlin/Any?|): R|kotlin/Unit| <inline=Unknown> {
R|<local>/x|.R|SubstitutionOverride</A.call: R|kotlin/Unit|>|(vararg(SAM(call@fun <anonymous>(y: R|kotlin/Any?|): R|kotlin/Unit| <inline=Unknown> {
Q|kotlin/Unit|
}
))
)))
}
@@ -1,11 +1,11 @@
FILE: main.kt
public final fun main(): R|kotlin/Unit| {
Q|JavaClass|.R|/JavaClass.foo*s|(<L> = foo@fun <anonymous>(): R|kotlin/Unit| <inline=NoInline> {
Q|JavaClass|.R|/JavaClass.foo*s|(<L> = SAM(foo@fun <anonymous>(): R|kotlin/Unit| <inline=NoInline> {
String()
}
)
R|/JavaClass.JavaClass|().R|/JavaClass.bar|(<L> = bar@fun <anonymous>(): R|kotlin/Unit| <inline=NoInline> {
))
R|/JavaClass.JavaClass|().R|/JavaClass.bar|(<L> = SAM(bar@fun <anonymous>(): R|kotlin/Unit| <inline=NoInline> {
String()
}
)
))
}
@@ -1,7 +1,7 @@
FILE: main.kt
public final fun test(): R|kotlin/Unit| {
R|/Foo.Foo|(<L> = Foo@fun <anonymous>(it: R|kotlin/Boolean|): R|kotlin/Boolean| <inline=NoInline> {
R|/Foo.Foo|(<L> = SAM(Foo@fun <anonymous>(it: R|kotlin/Boolean|): R|kotlin/Boolean| <inline=NoInline> {
^ R|<local>/it|
}
)
))
}
@@ -2,17 +2,17 @@ FILE: main.kt
public final fun foo(m: R|MyRunnable|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
Q|JavaUsage|.R|/JavaUsage.foo*s|(<L> = foo@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| <inline=NoInline> {
Q|JavaUsage|.R|/JavaUsage.foo*s|(<L> = SAM(foo@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| <inline=NoInline> {
^ CMP(>, R|<local>/x|.R|kotlin/Int.compareTo|(Int(1)))
}
)
Q|JavaUsage|.R|/JavaUsage.foo*s|(foo@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Boolean| <inline=NoInline> {
))
Q|JavaUsage|.R|/JavaUsage.foo*s|(SAM(foo@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Boolean| <inline=NoInline> {
^ CMP(>, R|<local>/it|.R|kotlin/Int.compareTo|(Int(1)))
}
)
))
lval x: R|(kotlin/Int) -> kotlin/Boolean| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| <inline=Unknown> {
^ CMP(>, R|<local>/x|.R|kotlin/Int.compareTo|(Int(1)))
}
Q|JavaUsage|.R|/JavaUsage.foo*s|(R|<local>/x|)
Q|JavaUsage|.R|/JavaUsage.foo*s|(SAM(R|<local>/x|))
}
@@ -2,17 +2,17 @@ FILE: main.kt
public final fun foo(m: R|MyRunnable|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
Q|JavaUsage|.R|/JavaUsage.foo*s|(<L> = foo@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean!| <inline=NoInline> {
Q|JavaUsage|.R|/JavaUsage.foo*s|(<L> = SAM(foo@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean!| <inline=NoInline> {
^ CMP(>, R|<local>/x|.R|kotlin/Int.compareTo|(Int(1)))
}
)
Q|JavaUsage|.R|/JavaUsage.foo*s|(foo@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Boolean!| <inline=NoInline> {
))
Q|JavaUsage|.R|/JavaUsage.foo*s|(SAM(foo@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Boolean!| <inline=NoInline> {
^ CMP(>, R|<local>/it|.R|kotlin/Int.compareTo|(Int(1)))
}
)
))
lval x: R|(kotlin/Int) -> kotlin/Boolean| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| <inline=Unknown> {
^ CMP(>, R|<local>/x|.R|kotlin/Int.compareTo|(Int(1)))
}
Q|JavaUsage|.R|/JavaUsage.foo*s|(R|<local>/x|)
Q|JavaUsage|.R|/JavaUsage.foo*s|(SAM(R|<local>/x|))
}
@@ -14,8 +14,8 @@ FILE: package2.kt
}
FILE: main.kt
public final fun main(): R|kotlin/Unit| {
R|p1/bar|(String(), String(), <L> = bar@fun <anonymous>(): R|kotlin/Unit| <inline=NoInline> {
R|p1/bar|(String(), String(), <L> = SAM(bar@fun <anonymous>(): R|kotlin/Unit| <inline=NoInline> {
^@bar Unit
}
)
))
}
@@ -5,7 +5,7 @@ FILE: main.kt
}
public final fun main(): R|kotlin/Unit| {
Q|OverridingUtil|.R|/OverridingUtil.createWithEqualityAxioms*s|(<L> = l1@fun <anonymous>(c1: R|TypeConstructor!|, c2: R|TypeConstructor!|): R|kotlin/Boolean| <inline=NoInline> {
Q|OverridingUtil|.R|/OverridingUtil.createWithEqualityAxioms*s|(<L> = SAM(l1@fun <anonymous>(c1: R|TypeConstructor!|, c2: R|TypeConstructor!|): R|kotlin/Boolean| <inline=NoInline> {
when () {
==(R|<local>/c1|.R|/TypeConstructor.x|, R|<local>/c2|.R|/TypeConstructor.x|) -> {
^@l1 Boolean(true)
@@ -14,5 +14,5 @@ FILE: main.kt
^ Boolean(false)
}
)
))
}
@@ -2,17 +2,17 @@ FILE: main.kt
public final fun foo(m: R|MyRunnable|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
Q|JavaUsage|.R|/JavaUsage.foo*s|(<L> = foo@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| <inline=NoInline> {
Q|JavaUsage|.R|/JavaUsage.foo*s|(<L> = SAM(foo@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| <inline=NoInline> {
^ CMP(>, R|<local>/x|.R|kotlin/Int.compareTo|(Int(1)))
}
)
Q|JavaUsage|.R|/JavaUsage.foo*s|(foo@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Boolean| <inline=NoInline> {
))
Q|JavaUsage|.R|/JavaUsage.foo*s|(SAM(foo@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Boolean| <inline=NoInline> {
^ CMP(>, R|<local>/it|.R|kotlin/Int.compareTo|(Int(1)))
}
)
))
lval x: R|(kotlin/Int) -> kotlin/Boolean| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| <inline=Unknown> {
^ CMP(>, R|<local>/x|.R|kotlin/Int.compareTo|(Int(1)))
}
Q|JavaUsage|.R|/JavaUsage.foo*s|(R|<local>/x|)
Q|JavaUsage|.R|/JavaUsage.foo*s|(SAM(R|<local>/x|))
}
@@ -1,6 +1,6 @@
FILE: referenceToJavaStdlib.kt
public final fun detectDirsWithTestsMapFileOnly(file: R|java/io/File|): R|kotlin/collections/List<kotlin/String>| {
Q|java/nio/file/Files|.R|java/nio/file/Files.walk*s|(R|<local>/file|.R|java/io/File.toPath|()).R|SubstitutionOverride<java/util/stream/Stream.filter: R|ft<java/util/stream/Stream<java/nio/file/Path!>, java/util/stream/Stream<java/nio/file/Path!>?>|>|(Q|java/nio/file/Files|::R|java/nio/file/Files.isRegularFile*s|)
Q|java/nio/file/Files|.R|java/nio/file/Files.walk*s|(R|<local>/file|.R|java/io/File.toPath|()).R|SubstitutionOverride<java/util/stream/Stream.filter: R|ft<java/util/stream/Stream<java/nio/file/Path!>, java/util/stream/Stream<java/nio/file/Path!>?>|>|(SAM(Q|java/nio/file/Files|::R|java/nio/file/Files.isRegularFile*s|))
}
public abstract interface A : R|kotlin/Any| {
}
@@ -16,5 +16,5 @@ FILE: sam.kt
}
public final fun main(): R|kotlin/Unit| {
lval a: R|A| = R|/A.A|()
R|/foo|(R|<local>/a|::R|/A.bar|)
R|/foo|(SAM(R|<local>/a|::R|/A.bar|))
}
@@ -14,10 +14,10 @@ FILE: hashTableWithForEach.kt
when () {
R|/DEBUG| -> {
^ Q|java/util/Collections|.R|java/util/Collections.unmodifiableSet*s|<R|ft<kotlin/collections/MutableMap.MutableEntry<K, V>, kotlin/collections/MutableMap.MutableEntry<K, V>?>|>(R|kotlin/collections/mutableSetOf|<R|kotlin/collections/MutableMap.MutableEntry<K, V>|>().R|kotlin/apply|<R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|>(<L> = apply@fun R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=EXACTLY_ONCE> {
this@R|/SomeHashTable|.R|/SomeHashTable.forEach|(<L> = forEach@fun <anonymous>(key: R|@EnhancedNullability K|, value: R|@EnhancedNullability V|): R|kotlin/Unit| <inline=NoInline> {
this@R|/SomeHashTable|.R|/SomeHashTable.forEach|(<L> = SAM(forEach@fun <anonymous>(key: R|@EnhancedNullability K|, value: R|@EnhancedNullability V|): R|kotlin/Unit| <inline=NoInline> {
this@R|special/anonymous|.R|SubstitutionOverride<kotlin/collections/MutableSet.add: R|kotlin/Boolean|>|(R|/SomeHashTable.Entry.Entry|<R|K|, R|V|>(R|<local>/key|, R|<local>/value|))
}
)
))
}
))
}
@@ -1,9 +1,9 @@
FILE: MapCompute.kt
public final fun <D> R|kotlin/collections/MutableMap<kotlin/String, kotlin/collections/MutableSet<D>>|.initAndAdd(key: R|kotlin/String|, value: R|D|): R|kotlin/Unit| {
this@R|/initAndAdd|.R|SubstitutionOverride<kotlin/collections/MutableMap.compute: R|kotlin/collections/MutableSet<D>?|>|(R|<local>/key|, <L> = compute@fun <anonymous>(<unused var>: R|@EnhancedNullability kotlin/String|, maybeValues: R|@EnhancedNullability kotlin/collections/MutableSet<D>?|): R|@EnhancedNullability kotlin/collections/MutableSet<D>?| <inline=NoInline> {
this@R|/initAndAdd|.R|SubstitutionOverride<kotlin/collections/MutableMap.compute: R|kotlin/collections/MutableSet<D>?|>|(R|<local>/key|, <L> = SAM(compute@fun <anonymous>(<unused var>: R|@EnhancedNullability kotlin/String|, maybeValues: R|@EnhancedNullability kotlin/collections/MutableSet<D>?|): R|@EnhancedNullability kotlin/collections/MutableSet<D>?| <inline=NoInline> {
lval setOfValues: R|kotlin/collections/MutableSet<D>| = R|<local>/maybeValues| ?: R|kotlin/collections/mutableSetOf|<R|D|>()
R|<local>/setOfValues|.R|SubstitutionOverride<kotlin/collections/MutableSet.add: R|kotlin/Boolean|>|(R|<local>/value|)
^ R|<local>/setOfValues|
}
)
))
}
@@ -6,12 +6,12 @@ FILE: test.kt
)
lval otherResult: R|kotlin/String!| = R|<local>/map|.R|SubstitutionOverride</MyMap.getOrDefault: R|kotlin/String!|>|(String(key), String(value))
lval anotherResult: R|kotlin/String?| = R|<local>/map|.R|SubstitutionOverride</MyMap.replace: R|kotlin/String?|>|(String(key), String(value))
R|<local>/map|.R|SubstitutionOverride</MyMap.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|@EnhancedNullability kotlin/String!|, value: R|@EnhancedNullability kotlin/String!|): R|kotlin/Unit| <inline=NoInline> {
R|<local>/map|.R|SubstitutionOverride</MyMap.forEach: R|kotlin/Unit|>|(<L> = SAM(forEach@fun <anonymous>(key: R|@EnhancedNullability kotlin/String!|, value: R|@EnhancedNullability kotlin/String!|): R|kotlin/Unit| <inline=NoInline> {
R|kotlin/io/println|(<strcat>(R|<local>/key|, String(: ), R|<local>/value|))
R|<local>/key|.R|kotlin/String.length|
R|<local>/value|.R|kotlin/String.length|
}
)
))
R|<local>/map|.R|kotlin/collections/forEach|<R|kotlin/String!|, R|kotlin/String!|>(<L> = forEach@fun <anonymous>(<destruct>: R|kotlin/collections/Map.Entry<kotlin/String!, kotlin/String!>|): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
lval key: R|kotlin/String!| = R|<local>/<destruct>|.R|kotlin/collections/component1|<R|kotlin/String!|, R|kotlin/String!|>()
lval value: R|kotlin/String!| = R|<local>/<destruct>|.R|kotlin/collections/component2|<R|kotlin/String!|, R|kotlin/String!|>()
@@ -31,12 +31,12 @@ FILE: test.kt
)
lval otherResult: R|kotlin/String| = R|<local>/map|.R|SubstitutionOverride<kotlin/collections/MutableMap.getOrDefault: R|kotlin/String|>|(String(key), String(value))
lval anotherResult: R|kotlin/String?| = R|<local>/map|.R|SubstitutionOverride<kotlin/collections/MutableMap.replace: R|kotlin/String?|>|(String(key), String(value))
R|<local>/map|.R|SubstitutionOverride<kotlin/collections/MutableMap.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|@EnhancedNullability kotlin/String|, value: R|@EnhancedNullability kotlin/String|): R|kotlin/Unit| <inline=NoInline> {
R|<local>/map|.R|SubstitutionOverride<kotlin/collections/MutableMap.forEach: R|kotlin/Unit|>|(<L> = SAM(forEach@fun <anonymous>(key: R|@EnhancedNullability kotlin/String|, value: R|@EnhancedNullability kotlin/String|): R|kotlin/Unit| <inline=NoInline> {
R|kotlin/io/println|(<strcat>(R|<local>/key|, String(: ), R|<local>/value|))
R|<local>/key|.R|kotlin/String.length|
R|<local>/value|.R|kotlin/String.length|
}
)
))
R|<local>/map|.R|kotlin/collections/forEach|<R|kotlin/String|, R|kotlin/String|>(<L> = forEach@fun <anonymous>(<destruct>: R|kotlin/collections/Map.Entry<kotlin/String, kotlin/String>|): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
lval key: R|kotlin/String| = R|<local>/<destruct>|.R|kotlin/collections/component1|<R|kotlin/String|, R|kotlin/String|>()
lval value: R|kotlin/String| = R|<local>/<destruct>|.R|kotlin/collections/component2|<R|kotlin/String|, R|kotlin/String|>()
@@ -1,10 +1,10 @@
FILE: test.kt
public final fun <D : R|kotlin/Any|> R|Call<D>|.testForEach(): R|kotlin/Unit| {
this@R|/testForEach|.R|/Call.arguments|.R|SubstitutionOverride<kotlin/collections/MutableMap.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|@EnhancedNullability kotlin/String!|, value: R|@EnhancedNullability kotlin/String!|): R|kotlin/Unit| <inline=NoInline> {
this@R|/testForEach|.R|/Call.arguments|.R|SubstitutionOverride<kotlin/collections/MutableMap.forEach: R|kotlin/Unit|>|(<L> = SAM(forEach@fun <anonymous>(key: R|@EnhancedNullability kotlin/String!|, value: R|@EnhancedNullability kotlin/String!|): R|kotlin/Unit| <inline=NoInline> {
R|<local>/key|.R|kotlin/String.length|
R|<local>/value|.R|kotlin/String.length|
}
)
))
this@R|/testForEach|.R|/Call.arguments|.R|kotlin/collections/forEach|<R|kotlin/String!|, R|kotlin/String!|>(<L> = forEach@fun <anonymous>(it: R|kotlin/collections/Map.Entry<kotlin/String!, kotlin/String!>|): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
R|<local>/it|.R|SubstitutionOverride<kotlin/collections/Map.Entry.key: R|kotlin/String!|>|.R|kotlin/String.length|
R|<local>/it|.R|SubstitutionOverride<kotlin/collections/Map.Entry.value: R|kotlin/String!|>|.R|kotlin/String.length|
@@ -1,7 +1,7 @@
FILE: mapMerge.kt
public final fun foo(x: R|kotlin/collections/MutableMap<kotlin/String, kotlin/collections/List<kotlin/String>>|): R|kotlin/Unit| {
R|<local>/x|.R|SubstitutionOverride<kotlin/collections/MutableMap.merge: R|kotlin/collections/List<kotlin/String>?|>|(String(), R|kotlin/collections/listOf|<R|kotlin/String|>(String()), <L> = merge@fun <anonymous>(a: R|@EnhancedNullability kotlin/collections/List<kotlin/String>|, b: R|@EnhancedNullability kotlin/collections/List<kotlin/String>|): R|@EnhancedNullability kotlin/collections/List<kotlin/String>?| <inline=NoInline> {
R|<local>/x|.R|SubstitutionOverride<kotlin/collections/MutableMap.merge: R|kotlin/collections/List<kotlin/String>?|>|(String(), R|kotlin/collections/listOf|<R|kotlin/String|>(String()), <L> = SAM(merge@fun <anonymous>(a: R|@EnhancedNullability kotlin/collections/List<kotlin/String>|, b: R|@EnhancedNullability kotlin/collections/List<kotlin/String>|): R|@EnhancedNullability kotlin/collections/List<kotlin/String>?| <inline=NoInline> {
^ R|<local>/a|.R|kotlin/collections/plus|<R|kotlin/String|>(R|<local>/b|)
}
)
))
}
@@ -2,10 +2,10 @@ FILE: test.kt
public final fun foo(): R|kotlin/Unit| {
lval externalsMap: R|kotlin/collections/MutableMap<java/io/File, kotlin/String?>| = R|kotlin/collections/mutableMapOf|<R|java/io/File|, R|kotlin/String?|>()
local final fun test(file: R|java/io/File|): R|kotlin/Unit| {
lval base: R|java/io/File!| = Q|your/ContainerUtil|.R|your/ContainerUtil.find*s|<R|java/io/File!|>(R|<local>/externalsMap|.R|SubstitutionOverride<kotlin/collections/MutableMap.keys: R|kotlin/collections/MutableSet<java/io/File>|>|, <L> = find@fun <anonymous>(it: R|java/io/File!|): R|kotlin/Boolean| <inline=NoInline> {
lval base: R|java/io/File!| = Q|your/ContainerUtil|.R|your/ContainerUtil.find*s|<R|java/io/File!|>(R|<local>/externalsMap|.R|SubstitutionOverride<kotlin/collections/MutableMap.keys: R|kotlin/collections/MutableSet<java/io/File>|>|, <L> = SAM(find@fun <anonymous>(it: R|java/io/File!|): R|kotlin/Boolean| <inline=NoInline> {
^ Q|my/FileUtil|.R|my/FileUtil.isAncestor*s|(R|<local>/it|, R|<local>/file|, Boolean(false))
}
)
))
}
}
@@ -1,7 +1,7 @@
FILE: removeIf.kt
public final fun test(collection: R|kotlin/collections/MutableCollection<kotlin/Boolean>|): R|kotlin/Unit| {
R|<local>/collection|.R|SubstitutionOverride<kotlin/collections/MutableCollection.removeIf: R|kotlin/Boolean|>|(<L> = removeIf@fun <anonymous>(it: R|@EnhancedNullability kotlin/Boolean|): R|kotlin/Boolean| <inline=NoInline> {
R|<local>/collection|.R|SubstitutionOverride<kotlin/collections/MutableCollection.removeIf: R|kotlin/Boolean|>|(<L> = SAM(removeIf@fun <anonymous>(it: R|@EnhancedNullability kotlin/Boolean|): R|kotlin/Boolean| <inline=NoInline> {
^ R|<local>/it|
}
)
))
}
@@ -2,8 +2,8 @@ FILE: samForComparator.kt
public final fun foo(x: R|kotlin/Comparator<in kotlin/CharSequence>|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
R|/foo|(<L> = foo@fun <anonymous>(x: R|kotlin/CharSequence!|, y: R|kotlin/CharSequence!|): R|kotlin/Int| <inline=NoInline> {
R|/foo|(<L> = SAM(foo@fun <anonymous>(x: R|kotlin/CharSequence!|, y: R|kotlin/CharSequence!|): R|kotlin/Int| <inline=NoInline> {
^ R|<local>/x|.R|kotlin/CharSequence.length|.R|kotlin/Int.minus|(R|<local>/y|.R|kotlin/CharSequence.length|)
}
)
))
}
@@ -10,10 +10,10 @@ FILE: typeAliasWithForEach.kt
public final typealias Arguments = R|kotlin/collections/Map<kotlin/String, ArgsInfo>|
public final fun R|Arguments|.deepCopy(): R|Arguments| {
lval result: R|java/util/HashMap<kotlin/String, ArgsInfo>| = R|java/util/HashMap.HashMap|<R|kotlin/String|, R|ArgsInfo|>()
this@R|/deepCopy|.R|SubstitutionOverride<kotlin/collections/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|@EnhancedNullability kotlin/String|, value: R|@EnhancedNullability ArgsInfo|): R|kotlin/Unit| <inline=NoInline> {
this@R|/deepCopy|.R|SubstitutionOverride<kotlin/collections/Map.forEach: R|kotlin/Unit|>|(<L> = SAM(forEach@fun <anonymous>(key: R|@EnhancedNullability kotlin/String|, value: R|@EnhancedNullability ArgsInfo|): R|kotlin/Unit| <inline=NoInline> {
R|<local>/result|.R|kotlin/collections/set|<R|kotlin/String|, R|ArgsInfo|>(R|<local>/key|, R|/ArgsInfoImpl.ArgsInfoImpl|(R|<local>/value|))
Unit
}
)
))
^deepCopy R|<local>/result|
}
@@ -531,6 +531,10 @@ class Fir2IrVisitor(
return convertToIrExpression(wrappedArgumentExpression.expression)
}
override fun visitSamConversionExpression(samConversionExpression: FirSamConversionExpression, data: Any?): IrElement {
return convertToIrExpression(samConversionExpression.expression)
}
override fun visitVarargArgumentsExpression(varargArgumentsExpression: FirVarargArgumentsExpression, data: Any?): IrElement {
return varargArgumentsExpression.convertWithOffsets { startOffset, endOffset ->
IrVarargImpl(
@@ -17,14 +17,9 @@ import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.FirSamResolver
import org.jetbrains.kotlin.fir.resolve.calls.FirFakeArgumentForCallableReference
import org.jetbrains.kotlin.fir.resolve.calls.ResolvedCallArgument
import org.jetbrains.kotlin.fir.resolve.calls.getExpectedType
import org.jetbrains.kotlin.fir.resolve.calls.isFunctional
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve
import org.jetbrains.kotlin.fir.scopes.processAllCallables
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
@@ -44,7 +39,6 @@ import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.model.TypeVariance
@@ -64,23 +58,6 @@ internal class AdapterGenerator(
private val samResolver = FirSamResolver(session, scopeSession)
private val starProjectionApproximator = object : AbstractConeSubstitutor(session.typeContext) {
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
if (type !is ConeClassLikeType || type.typeArguments.none { it == ConeStarProjection }) return null
val fir = type.lookupTag.toSymbol(session)?.fir as? FirTypeParameterRefsOwner ?: return null
val typeParameters = fir.typeParameters.map { it.symbol.fir }
if (typeParameters.size != type.typeArguments.size) return null
val newTypeArguments = typeParameters.zip(type.typeArguments).map { (parameter, argument) ->
if (argument == ConeStarProjection) {
parameter.bounds.first().coneType
} else {
argument
}
}
return type.withArguments(newTypeArguments.toTypedArray())
}
}
private fun ConeKotlinType.toIrType(typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT): IrType =
with(typeConverter) { toIrType(typeOrigin) }
@@ -422,8 +399,6 @@ internal class AdapterGenerator(
internal fun IrExpression.applySamConversionIfNeeded(
argument: FirExpression,
parameter: FirValueParameter?,
substitutor: ConeSubstitutor,
shouldUnwrapVarargType: Boolean = false
): IrExpression {
if (parameter == null) {
return this
@@ -431,28 +406,19 @@ internal class AdapterGenerator(
if (this is IrVararg) {
// element-wise SAM conversion if and only if we can build 1-to-1 mapping for elements.
return applyConversionOnVararg(argument) { firVarargArgument ->
applySamConversionIfNeeded(firVarargArgument, parameter, substitutor, shouldUnwrapVarargType = true)
applySamConversionIfNeeded(firVarargArgument, parameter)
}
}
if (!needSamConversion(argument, parameter)) {
return this
}
val parameterType = parameter.returnTypeRef.coneType
val substitutedParameterType =
starProjectionApproximator.substituteOrSelf(substitutor.substituteOrSelf(parameterType)).let {
if (shouldUnwrapVarargType)
it.arrayElementType() ?: it
else
it
}
val samFirType = substitutedParameterType.removeExternalProjections() ?: substitutedParameterType
if (!samFirType.isSamType) return this
val unwrappedArgument = argument.unwrapArgument()
if (unwrappedArgument !is FirSamConversionExpression) return this
val samFirType = unwrappedArgument.resolvedType.let { it.removeExternalProjections() ?: it }
val samType = samFirType.toIrType(ConversionTypeOrigin.DEFAULT)
// Make sure the converted IrType owner indeed has a single abstract method, since FunctionReferenceLowering relies on it.
return IrTypeOperatorCallImpl(
this.startOffset, this.endOffset, samType, IrTypeOperator.SAM_CONVERSION, samType,
castArgumentToFunctionalInterfaceForSamType(this, argument.resolvedType, samFirType)
castArgumentToFunctionalInterfaceForSamType(this, unwrappedArgument.expression.resolvedType, samFirType)
)
}
@@ -494,7 +460,7 @@ internal class AdapterGenerator(
val parameter = parameters.getOrNull(i) ?: return null
when {
argument.getVariance() == TypeVariance.IN -> {
!argument.isStarProjection() && argument.getVariance() == TypeVariance.IN -> {
// Just erasing `in` from the type projection would lead to an incorrect type for the SAM adapter,
// and error at runtime on JVM if invokedynamic + LambdaMetafactory is used, see KT-51868.
// So we do it "carefully". If we have a class `A<T>` and a method that takes e.g. `A<in String>`, we check
@@ -551,39 +517,6 @@ internal class AdapterGenerator(
return this
}
private fun needSamConversion(argument: FirExpression, parameter: FirValueParameter): Boolean {
// If the type of the argument is already an explicitly subtype of the type of the parameter, we don't need SAM conversion.
if (
AbstractTypeChecker.isSubtypeOf(
session.typeContext.newTypeCheckerState(
errorTypesEqualToAnything = false, stubTypesEqualToAnything = true
),
argument.resolvedType,
parameter.returnTypeRef.coneType,
isFromNullabilityConstraint = true
)
) {
return false
}
// If the expected type is a built-in functional type, we don't need SAM conversion.
val expectedType = argument.getExpectedType(parameter)
if (expectedType.isTypeParameterBased() || expectedType.isSomeFunctionType(session)) {
return false
}
// On the other hand, the actual type should be either a functional type or a subtype of a class that has a contributed `invoke`.
val expectedFunctionType = getFunctionTypeForPossibleSamType(parameter.returnTypeRef.coneType)
return argument.isFunctional(session, scopeSession, expectedFunctionType, ReturnTypeCalculatorForFullBodyResolve.Default)
}
private fun ConeKotlinType.isTypeParameterBased(): Boolean {
return when (this) {
is ConeTypeParameterType -> true
is ConeDefinitelyNotNullType -> original.isTypeParameterBased()
is ConeFlexibleType -> lowerBound.isTypeParameterBased()
else -> false
}
}
internal fun getFunctionTypeForPossibleSamType(parameterType: ConeKotlinType): ConeKotlinType? {
return samResolver.getFunctionTypeForPossibleSamType(parameterType)
}
@@ -640,7 +573,7 @@ internal class AdapterGenerator(
expectedFunctionalType: ConeClassLikeType,
argument: FirExpression
): IrSimpleFunctionSymbol? {
val argumentType = argument.resolvedType
val argumentType = ((argument as? FirSamConversionExpression)?.expression ?: argument).resolvedType
val argumentTypeWithInvoke = argumentType.findSubtypeOfBasicFunctionType(session, expectedFunctionalType) ?: return null
return if (argumentTypeWithInvoke.isSomeFunctionType(session)) {
@@ -837,19 +770,4 @@ internal class AdapterGenerator(
irAdapterFunction.parent = conversionScope.parent()!!
}
}
context(Fir2IrComponents)
private val ConeKotlinType.isSamType: Boolean
get() {
val classSymbol = this.lowerBoundIfFlexible().toRegularClassSymbol(session) ?: return false
if (!classSymbol.isInterface) return false
val scope = classSymbol.unsubstitutedScope()
var abstractNumber = 0
scope.processAllCallables {
if (it.isAbstract) {
abstractNumber++
}
}
return abstractNumber == 1
}
}
@@ -1062,8 +1062,6 @@ class CallAndReferenceGenerator(
irArgument = irArgument.insertSpecialCast(argument, argumentType, unsubstitutedParameterType)
}
}
// TODO: Applying SAM conversion should be extracted to a separate function, which will call
// convertArgument with original functional type as expected type, see KT-62847, KT-63345
with(adapterGenerator) {
if (parameter?.returnTypeRef is FirResolvedTypeRef) {
// Java type case (from annotations)
@@ -1071,7 +1069,7 @@ class CallAndReferenceGenerator(
val unwrappedParameterType = if (parameter.isVararg) parameterType.arrayElementType()!! else parameterType
val samFunctionType = getFunctionTypeForPossibleSamType(unwrappedParameterType)
irArgument = irArgument.applySuspendConversionIfNeeded(argument, samFunctionType ?: unwrappedParameterType)
irArgument = irArgument.applySamConversionIfNeeded(argument, parameter, substitutor)
irArgument = irArgument.applySamConversionIfNeeded(argument, parameter)
}
}
return irArgument
@@ -49813,6 +49813,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/sam/kt59858.kt");
}
@Test
@TestMetadata("noConversionFromSamToSam.kt")
public void testNoConversionFromSamToSam() throws Exception {
runTest("compiler/testData/codegen/box/sam/noConversionFromSamToSam.kt");
}
@Test
@TestMetadata("nonInlinedSamWrapper.kt")
public void testNonInlinedSamWrapper() throws Exception {
@@ -49813,6 +49813,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
runTest("compiler/testData/codegen/box/sam/kt59858.kt");
}
@Test
@TestMetadata("noConversionFromSamToSam.kt")
public void testNoConversionFromSamToSam() throws Exception {
runTest("compiler/testData/codegen/box/sam/noConversionFromSamToSam.kt");
}
@Test
@TestMetadata("nonInlinedSamWrapper.kt")
public void testNonInlinedSamWrapper() throws Exception {
@@ -49813,6 +49813,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/sam/kt59858.kt");
}
@Test
@TestMetadata("noConversionFromSamToSam.kt")
public void testNoConversionFromSamToSam() throws Exception {
runTest("compiler/testData/codegen/box/sam/noConversionFromSamToSam.kt");
}
@Test
@TestMetadata("nonInlinedSamWrapper.kt")
public void testNonInlinedSamWrapper() throws Exception {
@@ -7,12 +7,10 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.builtins.functions.isBasicFunctionOrKFunction
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.lookupTracker
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.resolve.*
@@ -23,7 +21,6 @@ import org.jetbrains.kotlin.fir.resolve.inference.preprocessCallableReference
import org.jetbrains.kotlin.fir.resolve.inference.preprocessLambdaArgument
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedTypeDeclaration
import org.jetbrains.kotlin.fir.returnExpressions
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.types.*
@@ -39,7 +36,6 @@ import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.model.CaptureStatus
import org.jetbrains.kotlin.types.model.TypeSystemCommonSuperTypesContext
import org.jetbrains.kotlin.types.model.typeConstructor
import org.jetbrains.kotlin.utils.addToStdlib.runIf
val SAM_LOOKUP_NAME = Name.special("<SAM-CONSTRUCTOR>")
@@ -496,16 +492,29 @@ private fun Candidate.getExpectedTypeWithSAMConversion(
scopeSession: ScopeSession,
argument: FirExpression,
candidateExpectedType: ConeKotlinType,
context: ResolutionContext
context: ResolutionContext,
): ConeKotlinType? {
if (candidateExpectedType.isSomeFunctionType(session)) return null
val expectedFunctionType = context.bodyResolveComponents.samResolver.getFunctionTypeForPossibleSamType(candidateExpectedType)
?: return null
return runIf(argument.isFunctional(session, scopeSession, expectedFunctionType, context.returnTypeCalculator)) {
usesSAM = true
expectedFunctionType
if (!argument.shouldUseSamConversion(
session,
scopeSession,
candidateExpectedType = candidateExpectedType,
expectedFunctionType = expectedFunctionType,
context.returnTypeCalculator
)
) {
return null
}
val samConversions = functionTypesOfSamConversions
?: hashMapOf<FirExpression, ConeKotlinType>().also { functionTypesOfSamConversions = it }
samConversions[argument.unwrapArgument()] = expectedFunctionType
return expectedFunctionType
}
private fun getExpectedTypeWithImplicitIntegerCoercion(
@@ -531,10 +540,11 @@ private fun getExpectedTypeWithImplicitIntegerCoercion(
return argumentType?.withNullability(candidateExpectedType.nullability, session.typeContext)
}
fun FirExpression.isFunctional(
fun FirExpression.shouldUseSamConversion(
session: FirSession,
scopeSession: ScopeSession,
expectedFunctionType: ConeKotlinType?,
candidateExpectedType: ConeKotlinType,
expectedFunctionType: ConeKotlinType,
returnTypeCalculator: ReturnTypeCalculator,
): Boolean {
when (unwrapArgument()) {
@@ -542,10 +552,15 @@ fun FirExpression.isFunctional(
else -> {
// Either a functional type or a subtype of a class that has a contributed `invoke`.
val coneType = resolvedType
// Argument might have an intersection type between FunctionN and the SAM type from a smart cast, in which case we don't want to use
// SAM conversion.
if (coneType.isSubtypeOf(candidateExpectedType, session)) {
return false
}
if (coneType.isSomeFunctionType(session)) {
return true
}
val classLikeExpectedFunctionType = expectedFunctionType?.lowerBoundIfFlexible() as? ConeClassLikeType
val classLikeExpectedFunctionType = expectedFunctionType.lowerBoundIfFlexible() as? ConeClassLikeType
if (classLikeExpectedFunctionType == null || coneType is ConeIntegerLiteralType) {
return false
}
@@ -84,7 +84,7 @@ class Candidate(
lateinit var freshVariables: List<ConeTypeVariable>
var resultingTypeForCallableReference: ConeKotlinType? = null
var outerConstraintBuilderEffect: (ConstraintSystemOperation.() -> Unit)? = null
var usesSAM: Boolean = false
val usesSAM: Boolean get() = functionTypesOfSamConversions != null
internal var callableReferenceAdaptation: CallableReferenceAdaptation? = null
set(value) {
@@ -99,6 +99,7 @@ class Candidate(
var argumentMapping: LinkedHashMap<FirExpression, FirValueParameter>? = null
var numDefaults: Int = 0
var functionTypesOfSamConversions: HashMap<FirExpression, ConeKotlinType>? = null
lateinit var typeArgumentMapping: TypeArgumentMapping
val postponedAtoms = mutableListOf<PostponedResolvedAtom>()
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isInline
@@ -12,6 +14,7 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.buildSamConversionExpression
import org.jetbrains.kotlin.fir.expressions.impl.FirPropertyAccessExpressionImpl
import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildResolvedCallableReference
@@ -316,7 +319,9 @@ class FirCallCompletionResultsWriterTransformer(
}
}
val expectedArgumentsTypeMapping = runIf(!calleeReference.isError) { subCandidate.createArgumentsMapping() }
result.argumentList.transformArguments(this, expectedArgumentsTypeMapping)
result.transformWithExpectedTypes(expectedArgumentsTypeMapping)
result.replaceConeTypeOrNull(resultType)
session.lookupTracker?.recordTypeResolveAsLookup(resultType, functionCall.source, context.file.source)
@@ -330,6 +335,45 @@ class FirCallCompletionResultsWriterTransformer(
return result
}
private fun FirCall.transformWithExpectedTypes(expectedArgumentsTypeMapping: ExpectedArgumentType.ArgumentsMap?) {
class SamConversionInsertionTransformer : FirTransformer<Nothing?>() {
override fun <E : FirElement> transformElement(element: E, data: Nothing?): E {
// We want to handle only the most top-level "real" expressions
// We only recursively transform named, spread, lambda argument and vararg expressions.
if (element is FirWrappedArgumentExpression || element is FirVarargArgumentsExpression) {
@Suppress("UNCHECKED_CAST")
return element.transformChildren(this, null) as E
}
// Once we encounter the first "real" expression, we delegate to the outer transformer.
val transformed = element.transformSingle(this@FirCallCompletionResultsWriterTransformer, expectedArgumentsTypeMapping)
// Finally, the result can be wrapped in a SAM conversion if necessary.
if (transformed is FirExpression) {
val key = (element as? FirAnonymousFunctionExpression)?.anonymousFunction ?: element
if (expectedArgumentsTypeMapping?.samFunctionTypes?.get(key) != null) {
val expectedArgumentType = expectedArgumentsTypeMapping.getExpectedType(key)
@Suppress("UNCHECKED_CAST")
expectedArgumentType?.let { return transformed.wrapInSamExpression(it) as E }
}
}
return transformed
}
}
argumentList.transformArguments(SamConversionInsertionTransformer(), null)
}
private fun FirExpression.wrapInSamExpression(expectedArgumentType: ConeKotlinType): FirExpression {
return buildSamConversionExpression {
expression = this@wrapInSamExpression
coneTypeOrNull = expectedArgumentType.withNullability(resolvedType.nullability, session.typeContext)
.let { typeApproximator.approximateToSuperType(it, TypeApproximatorConfiguration.TypeArgumentApproximation) ?: it }
source = this@wrapInSamExpression.source?.fakeElement(KtFakeSourceElementKind.SamConversion)
}
}
private val FirBasedSymbol<*>.isArrayConstructorWithLambda: Boolean
get() {
val constructor = (this as? FirConstructorSymbol)?.fir ?: return false
@@ -501,18 +545,23 @@ class FirCallCompletionResultsWriterTransformer(
}
}
private fun FirTypeRef.substitute(candidate: Candidate): ConeKotlinType =
coneType.let { candidate.substitutor.substituteOrSelf(it) }
.let { finallySubstituteOrSelf(it) }
private fun FirTypeRef.substitute(candidate: Candidate): ConeKotlinType {
return coneType.substitute(candidate)
}
private fun Candidate.createArgumentsMapping(): ExpectedArgumentType? {
private fun ConeKotlinType.substitute(candidate: Candidate): ConeKotlinType {
return finallySubstituteOrSelf(candidate.substitutor.substituteOrSelf(this))
}
private fun Candidate.createArgumentsMapping(): ExpectedArgumentType.ArgumentsMap? {
val lambdasReturnType = postponedAtoms.filterIsInstance<ResolvedLambdaAtom>().associate {
Pair(it.atom, finallySubstituteOrSelf(substitutor.substituteOrSelf(it.returnType)))
}
val isIntegerOperator = symbol.isWrappedIntegerOperator()
val arguments = argumentMapping?.map { (argument, valueParameter) ->
var samConversions: MutableMap<FirElement, ConeKotlinType>? = null
val arguments = argumentMapping?.flatMap { (argument, valueParameter) ->
val expectedType = when {
isIntegerOperator -> ConeIntegerConstantOperatorTypeImpl(
isUnsigned = symbol.isWrappedIntegerOperatorForUnsignedType() && callInfo.name in binaryOperatorsWithSignedArgument,
@@ -522,16 +571,19 @@ class FirCallCompletionResultsWriterTransformer(
else -> valueParameter.returnTypeRef.substitute(this)
}
val unwrappedArgument: FirElement = when (val unwrappedArgument = argument.unwrapArgument()) {
is FirAnonymousFunctionExpression -> unwrappedArgument.anonymousFunction
else -> unwrappedArgument
argument.unwrapAndFlattenArgument(flattenArrays = false).map {
val element: FirElement = (it as? FirAnonymousFunctionExpression)?.anonymousFunction ?: it
val samFunctionType = functionTypesOfSamConversions?.get(it)
if (samFunctionType != null) {
if (samConversions == null) samConversions = mutableMapOf()
samConversions!![element] = samFunctionType.substitute(this)
}
element to expectedType
}
unwrappedArgument to expectedType
}?.toMap()
if (lambdasReturnType.isEmpty() && arguments.isNullOrEmpty()) return null
return ExpectedArgumentType.ArgumentsMap(arguments ?: emptyMap(), lambdasReturnType)
return ExpectedArgumentType.ArgumentsMap(arguments ?: emptyMap(), lambdasReturnType, samConversions ?: emptyMap())
}
override fun transformDelegatedConstructorCall(
@@ -554,7 +606,7 @@ class FirCallCompletionResultsWriterTransformer(
}
val argumentsMapping = runIf(!calleeReference.isError) { subCandidate.createArgumentsMapping() }
delegatedConstructorCall.argumentList.transformArguments(this, argumentsMapping)
delegatedConstructorCall.transformWithExpectedTypes(argumentsMapping)
return delegatedConstructorCall.apply {
replaceCalleeReference(calleeReference.toResolvedReference())
@@ -637,7 +689,11 @@ class FirCallCompletionResultsWriterTransformer(
// a built-in functional type, no-brainer
expectedArgumentType.isSomeFunctionType(session) -> expectedArgumentType
// fun interface (a.k.a. SAM), then unwrap it and build a functional type from that interface function
else -> samResolver.getFunctionTypeForPossibleSamType(expectedArgumentType)?.lowerBoundIfFlexible()
else -> {
val samFunctionType = (data as? ExpectedArgumentType.ArgumentsMap)?.samFunctionTypes?.get(anonymousFunction)
?: samResolver.getFunctionTypeForPossibleSamType(expectedArgumentType)
samFunctionType?.lowerBoundIfFlexible()
}
}
}
@@ -896,6 +952,7 @@ sealed class ExpectedArgumentType {
class ArgumentsMap(
val map: Map<FirElement, ConeKotlinType>,
val lambdasReturnTypes: Map<FirAnonymousFunction, ConeKotlinType>,
val samFunctionTypes: Map<FirElement, ConeKotlinType>,
) : ExpectedArgumentType()
class ExpectedType(val type: ConeKotlinType) : ExpectedArgumentType()
@@ -1547,18 +1547,26 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
typeRef = initializer.resolvedType.toFirResolvedTypeRef(initializer.source?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)),
)
val indexVariables = lhsGetCall.arguments.flatMap {
if (it is FirVarargArgumentsExpression)
it.arguments
else
listOf(it)
}.mapIndexed { i, index ->
val flattenedGetCallArguments = buildList {
for (argument in lhsGetCall.arguments) {
if (argument is FirVarargArgumentsExpression) {
addAll(argument.arguments)
} else {
add(argument)
}
}
}
val indexVariables = flattenedGetCallArguments.mapIndexed { i, index ->
// If the get call arguments are SAM converted, unwrap the SAM conversion.
// Otherwise, we might fail resolution if the get and set operator parameter types are different
// (different SAM types or one is a SAM type and the other isn't).
val unwrappedSamIndex = (index as? FirSamConversionExpression)?.expression ?: index
generateTemporaryVariable(
session.moduleData,
source = index.source?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment),
source = unwrappedSamIndex.source?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment),
name = SpecialNames.subscribeOperatorIndex(i),
initializer = index,
typeRef = index.resolvedType.toFirResolvedTypeRef(),
initializer = unwrappedSamIndex,
typeRef = unwrappedSamIndex.resolvedType.toFirResolvedTypeRef(),
)
}
@@ -1568,6 +1576,17 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
val arrayAccess = arrayVariable.toQualifiedAccess()
val indicesQualifiedAccess = indexVariables.map { it.toQualifiedAccess() }
// If the get call arguments were SAM conversions, they were unwrapped for the variable initializers.
// We need to reapply the SAM conversions here because the get call won't be completed again (where the SAM conversions could be
// applied automatically).
// SAM conversions will be applied automatically for the set call during completion.
val indicesQualifiedAccessForGet = indicesQualifiedAccess.mapIndexed { index, qualifiedAccess ->
val samConversion = flattenedGetCallArguments[index] as? FirSamConversionExpression ?: return@mapIndexed qualifiedAccess
buildSamConversionExpressionCopy(samConversion) {
expression = qualifiedAccess
}
}
val getCall = buildFunctionCall {
source = augmentedArraySetCall.arrayAccessSource?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)
explicitReceiver = arrayAccess
@@ -1585,14 +1604,14 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
arguments += if (argument is FirVarargArgumentsExpression) {
buildVarargArgumentsExpression {
val varargSize = argument.arguments.size
arguments += indicesQualifiedAccess.subList(i, i + varargSize)
arguments += indicesQualifiedAccessForGet.subList(i, i + varargSize)
i += varargSize
source = argument.source
coneTypeOrNull = argument.resolvedType
varargElementType = argument.varargElementType
}
} else {
indicesQualifiedAccess[i++]
indicesQualifiedAccessForGet[i++]
}
}
}
@@ -288,6 +288,9 @@ sealed class KtFakeSourceElementKind(final override val shouldSkipErrorTypeRepor
// For provided parameters inside a script
object ScriptParameter : KtFakeSourceElementKind()
// When a lambda is converted to a SAM type, the expression is wrapped in an extra node
object SamConversion : KtFakeSourceElementKind()
}
sealed class AbstractKtSourceElement {
+2 -2
View File
@@ -9,8 +9,8 @@ FILE fqName:<root> fileName:/box.kt
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CONSTRUCTOR_CALL 'public constructor <init> (filter: @[FlexibleNullability] <root>.Condition<in @[FlexibleNullability] kotlin.String?>?) declared in <root>.J' type=<root>.J origin=null
filter: TYPE_OP type=@[FlexibleNullability] <root>.Condition<kotlin.Any?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] <root>.Condition<kotlin.Any?>?
TYPE_OP type=@[FlexibleNullability] kotlin.Function1<@[FlexibleNullability] kotlin.Any?, kotlin.Boolean>? origin=IMPLICIT_CAST typeOperand=@[FlexibleNullability] kotlin.Function1<@[FlexibleNullability] kotlin.Any?, kotlin.Boolean>?
filter: TYPE_OP type=<root>.Condition<kotlin.Any?>? origin=SAM_CONVERSION typeOperand=<root>.Condition<kotlin.Any?>?
TYPE_OP type=kotlin.Function1<@[FlexibleNullability] kotlin.Any?, kotlin.Boolean>? origin=IMPLICIT_CAST typeOperand=kotlin.Function1<@[FlexibleNullability] kotlin.Any?, kotlin.Boolean>?
GET_VAR 'filter: kotlin.Function1<kotlin.String, kotlin.Boolean>? declared in <root>.foo' type=kotlin.Function1<kotlin.String, kotlin.Boolean>? origin=null
RETURN type=kotlin.Nothing from='public final fun foo (filter: kotlin.Function1<kotlin.String, kotlin.Boolean>?): kotlin.String declared in <root>'
CONST String type=kotlin.String value="OK"
@@ -0,0 +1,21 @@
// TARGET_BACKEND: JVM
// FILE: Sam.java
public interface Sam<T> {
T foo();
}
// FILE: Connection.java
public interface Connection {
<T> T accept(Sam<T> sam);
}
// FILE: box.kt
fun test(sam: Sam<*>, c: Connection): Any {
return c.accept(sam)
}
fun box(): String {
return test({ "OK" }, object: Connection {
override fun <T> accept(sam: Sam<T>) = sam.foo()
}) as String
}
@@ -6,7 +6,7 @@ FILE fqName:<root> fileName:/genericSamProjectedOut.kt
<class: A>: kotlin.String
CALL 'public open fun someFunction (hello: @[FlexibleNullability] example.Hello<@[FlexibleNullability] A of example.SomeJavaClass?>?): kotlin.Unit declared in example.SomeJavaClass' type=kotlin.Unit origin=null
$this: GET_VAR 'var a: example.SomeJavaClass<out kotlin.String> declared in <root>.test' type=example.SomeJavaClass<out kotlin.String> origin=null
hello: TYPE_OP type=@[FlexibleNullability] example.Hello<out @[FlexibleNullability] kotlin.String?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] example.Hello<out @[FlexibleNullability] kotlin.String?>?
hello: TYPE_OP type=example.Hello<out @[FlexibleNullability] kotlin.String?> origin=SAM_CONVERSION typeOperand=example.Hello<out @[FlexibleNullability] kotlin.String?>
FUN_EXPR type=kotlin.Function1<@[FlexibleNullability] kotlin.String?, kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:@[FlexibleNullability] kotlin.String?) returnType:kotlin.Unit
VALUE_PARAMETER name:it index:0 type:@[FlexibleNullability] kotlin.String?
@@ -16,7 +16,7 @@ FILE fqName:<root> fileName:/genericSamProjectedOut.kt
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public open fun plus (hello: @[FlexibleNullability] example.Hello<@[FlexibleNullability] A of example.SomeJavaClass?>?): @[FlexibleNullability] example.SomeJavaClass<@[FlexibleNullability] A of example.SomeJavaClass?>? declared in example.SomeJavaClass' type=@[FlexibleNullability] example.SomeJavaClass<out @[FlexibleNullability] kotlin.String?>? origin=PLUS
$this: GET_VAR 'var a: example.SomeJavaClass<out kotlin.String> declared in <root>.test' type=example.SomeJavaClass<out kotlin.String> origin=null
hello: TYPE_OP type=@[FlexibleNullability] example.Hello<out @[FlexibleNullability] kotlin.String?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] example.Hello<out @[FlexibleNullability] kotlin.String?>?
hello: TYPE_OP type=example.Hello<out @[FlexibleNullability] kotlin.String?> origin=SAM_CONVERSION typeOperand=example.Hello<out @[FlexibleNullability] kotlin.String?>
FUN_EXPR type=kotlin.Function1<@[FlexibleNullability] kotlin.String?, kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:@[FlexibleNullability] kotlin.String?) returnType:kotlin.Unit
VALUE_PARAMETER name:it index:0 type:@[FlexibleNullability] kotlin.String?
@@ -25,7 +25,7 @@ FILE fqName:<root> fileName:/genericSamProjectedOut.kt
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: @[FlexibleNullability] example.Hello<@[FlexibleNullability] A of example.SomeJavaClass?>?): kotlin.Unit declared in example.SomeJavaClass' type=kotlin.Unit origin=null
$this: GET_VAR 'var a: example.SomeJavaClass<out kotlin.String> declared in <root>.test' type=example.SomeJavaClass<out kotlin.String> origin=null
hello: TYPE_OP type=@[FlexibleNullability] example.Hello<out @[FlexibleNullability] kotlin.String?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] example.Hello<out @[FlexibleNullability] kotlin.String?>?
hello: TYPE_OP type=example.Hello<out @[FlexibleNullability] kotlin.String?> origin=SAM_CONVERSION typeOperand=example.Hello<out @[FlexibleNullability] kotlin.String?>
FUN_EXPR type=kotlin.Function1<@[FlexibleNullability] kotlin.String?, kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:@[FlexibleNullability] kotlin.String?) returnType:kotlin.Unit
VALUE_PARAMETER name:it index:0 type:@[FlexibleNullability] kotlin.String?
@@ -35,7 +35,7 @@ FILE fqName:<root> fileName:/genericSamProjectedOut.kt
SET_VAR 'var a: example.SomeJavaClass<out kotlin.String> declared in <root>.test' type=kotlin.Unit origin=EQ
CALL 'public open fun plus (hello: @[FlexibleNullability] example.Hello<@[FlexibleNullability] A of example.SomeJavaClass?>?): @[FlexibleNullability] example.SomeJavaClass<@[FlexibleNullability] A of example.SomeJavaClass?>? declared in example.SomeJavaClass' type=@[FlexibleNullability] example.SomeJavaClass<out @[FlexibleNullability] kotlin.String?>? origin=null
$this: GET_VAR 'var a: example.SomeJavaClass<out kotlin.String> declared in <root>.test' type=example.SomeJavaClass<out kotlin.String> origin=null
hello: TYPE_OP type=@[FlexibleNullability] example.Hello<out @[FlexibleNullability] kotlin.String?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] example.Hello<out @[FlexibleNullability] kotlin.String?>?
hello: TYPE_OP type=example.Hello<out @[FlexibleNullability] kotlin.String?> origin=SAM_CONVERSION typeOperand=example.Hello<out @[FlexibleNullability] kotlin.String?>
FUN_EXPR type=kotlin.Function1<@[FlexibleNullability] kotlin.String?, kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:@[FlexibleNullability] kotlin.String?) returnType:kotlin.Unit
VALUE_PARAMETER name:it index:0 type:@[FlexibleNullability] kotlin.String?
@@ -45,7 +45,7 @@ FILE fqName:<root> fileName:/genericSamProjectedOut.kt
CALL 'public open fun set (i: kotlin.Int, hello: @[FlexibleNullability] example.Hello<@[FlexibleNullability] A of example.SomeJavaClass?>?): kotlin.Unit declared in example.SomeJavaClass' type=kotlin.Unit origin=null
$this: GET_VAR 'var a: example.SomeJavaClass<out kotlin.String> declared in <root>.test' type=example.SomeJavaClass<out kotlin.String> origin=null
i: CONST Int type=kotlin.Int value=0
hello: TYPE_OP type=@[FlexibleNullability] example.Hello<out @[FlexibleNullability] kotlin.String?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] example.Hello<out @[FlexibleNullability] kotlin.String?>?
hello: TYPE_OP type=example.Hello<out @[FlexibleNullability] kotlin.String?> origin=SAM_CONVERSION typeOperand=example.Hello<out @[FlexibleNullability] kotlin.String?>
FUN_EXPR type=kotlin.Function1<@[FlexibleNullability] kotlin.String?, kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:@[FlexibleNullability] kotlin.String?) returnType:kotlin.Unit
VALUE_PARAMETER name:it index:0 type:@[FlexibleNullability] kotlin.String?
@@ -3,21 +3,21 @@ fun test() {
a.someFunction(hello = local fun <anonymous>(it: @FlexibleNullability String?) {
return Unit
}
/*-> @FlexibleNullability Hello<out @FlexibleNullability String?>? */)
/*-> Hello<out @FlexibleNullability String?> */)
a.plus(hello = local fun <anonymous>(it: @FlexibleNullability String?) {
return Unit
}
/*-> @FlexibleNullability Hello<out @FlexibleNullability String?>? */) /*~> Unit */
/*-> Hello<out @FlexibleNullability String?> */) /*~> Unit */
a.get(hello = local fun <anonymous>(it: @FlexibleNullability String?) {
return Unit
}
/*-> @FlexibleNullability Hello<out @FlexibleNullability String?>? */)
/*-> Hello<out @FlexibleNullability String?> */)
a = a.plus(hello = local fun <anonymous>(it: @FlexibleNullability String?) {
return Unit
}
/*-> @FlexibleNullability Hello<out @FlexibleNullability String?>? */)
/*-> Hello<out @FlexibleNullability String?> */)
a.set(i = 0, hello = local fun <anonymous>(it: @FlexibleNullability String?) {
return Unit
}
/*-> @FlexibleNullability Hello<out @FlexibleNullability String?>? */)
/*-> Hello<out @FlexibleNullability String?> */)
}
@@ -12,7 +12,7 @@ FILE fqName:<root> fileName:/genericSamSmartcast.kt
CALL 'public open fun call (block: @[FlexibleNullability] <root>.A.I<@[FlexibleNullability] T of <root>.A?>?): @[FlexibleNullability] kotlin.String? declared in <root>.A' type=@[FlexibleNullability] 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=@[FlexibleNullability] <root>.A.I<out @[FlexibleNullability] kotlin.Any?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] <root>.A.I<out @[FlexibleNullability] kotlin.Any?>?
block: TYPE_OP type=<root>.A.I<out @[FlexibleNullability] kotlin.Any?> origin=SAM_CONVERSION typeOperand=<root>.A.I<out @[FlexibleNullability] kotlin.Any?>
FUN_EXPR type=kotlin.Function1<kotlin.Any?, @[FlexibleNullability] kotlin.String?> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (y:kotlin.Any?) returnType:@[FlexibleNullability] kotlin.String?
VALUE_PARAMETER name:y index:0 type:kotlin.Any?
@@ -4,9 +4,8 @@ fun f(x: Any): String {
return x /*as A<*> */.call(block = local fun <anonymous>(y: Any?): @FlexibleNullability String? {
return "OK"
}
/*-> @FlexibleNullability I<out @FlexibleNullability Any?>? */) /*!! String */
/*-> I<out @FlexibleNullability Any?> */) /*!! String */
}
}
return "Fail"
}
@@ -0,0 +1,11 @@
FILE fqName:<root> fileName:/samByProjectedType.kt
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
CALL 'public open fun bar (j: @[FlexibleNullability] <root>.J<*>?): kotlin.Unit declared in <root>.H' type=kotlin.Unit origin=null
j: TYPE_OP type=<root>.J<@[FlexibleNullability] kotlin.Any?> origin=SAM_CONVERSION typeOperand=<root>.J<@[FlexibleNullability] kotlin.Any?>
FUN_EXPR type=kotlin.Function1<kotlin.Any, @[FlexibleNullability] kotlin.Any?> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (x:kotlin.Any) returnType:@[FlexibleNullability] kotlin.Any?
VALUE_PARAMETER name:x index:0 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (x: kotlin.Any): @[FlexibleNullability] kotlin.Any? declared in <root>.test1'
GET_VAR 'x: kotlin.Any declared in <root>.test1.<anonymous>' type=kotlin.Any origin=null
@@ -0,0 +1,6 @@
fun test1() {
bar(j = local fun <anonymous>(x: Any): @FlexibleNullability Any? {
return x
}
/*-> J<@FlexibleNullability Any?> */)
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// TARGET_BACKEND: JVM
// FILE: samByProjectedType.kt
@@ -0,0 +1,114 @@
FILE fqName:<root> fileName:/samConversionInGenericConstructorCall.kt
FUN name:test3 visibility:public modality:FINAL <> (f1:kotlin.Function1<kotlin.String, kotlin.String>, f2:kotlin.Function1<kotlin.Int, kotlin.String>) returnType:<root>.C.D<@[FlexibleNullability] kotlin.Int?, @[FlexibleNullability] kotlin.String?>
VALUE_PARAMETER name:f1 index:0 type:kotlin.Function1<kotlin.String, kotlin.String>
VALUE_PARAMETER name:f2 index:1 type:kotlin.Function1<kotlin.Int, kotlin.String>
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test3 (f1: kotlin.Function1<kotlin.String, kotlin.String>, f2: kotlin.Function1<kotlin.Int, kotlin.String>): <root>.C.D<@[FlexibleNullability] kotlin.Int?, @[FlexibleNullability] kotlin.String?> declared in <root>'
CONSTRUCTOR_CALL 'public constructor <init> (jxy: @[FlexibleNullability] <root>.J<@[FlexibleNullability] X of <root>.C?, @[FlexibleNullability] Y of <root>.C.D?>?) declared in <root>.C.D' type=<root>.C.D<@[FlexibleNullability] kotlin.Int?, @[FlexibleNullability] kotlin.String?> origin=null
<class: Y>: @[FlexibleNullability] kotlin.Int?
$outer: CONSTRUCTOR_CALL 'public constructor <init> (jxx: @[FlexibleNullability] <root>.J<@[FlexibleNullability] X of <root>.C?, @[FlexibleNullability] X of <root>.C?>?) declared in <root>.C' type=<root>.C<@[FlexibleNullability] kotlin.String?> origin=null
<class: X>: @[FlexibleNullability] kotlin.String?
jxx: TYPE_OP type=<root>.J<@[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.String?> origin=SAM_CONVERSION typeOperand=<root>.J<@[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.String?>
GET_VAR 'f1: kotlin.Function1<kotlin.String, kotlin.String> declared in <root>.test3' type=kotlin.Function1<kotlin.String, kotlin.String> origin=null
jxy: TYPE_OP type=<root>.J<@[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.Int?> origin=SAM_CONVERSION typeOperand=<root>.J<@[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.Int?>
GET_VAR 'f2: kotlin.Function1<kotlin.Int, kotlin.String> declared in <root>.test3' type=kotlin.Function1<kotlin.Int, kotlin.String> origin=null
CLASS CLASS name:Outer modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Outer<T1 of <root>.Outer>
TYPE_PARAMETER name:T1 index:0 variance: superTypes:[kotlin.Any?] reified:false
CONSTRUCTOR visibility:public <> (j11:<root>.J<T1 of <root>.Outer, T1 of <root>.Outer>) returnType:<root>.Outer<T1 of <root>.Outer> [primary]
VALUE_PARAMETER name:j11 index:0 type:<root>.J<T1 of <root>.Outer, T1 of <root>.Outer>
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Outer modality:FINAL visibility:public superTypes:[kotlin.Any]'
PROPERTY name:j11 visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:j11 type:<root>.J<T1 of <root>.Outer, T1 of <root>.Outer> visibility:private [final]
EXPRESSION_BODY
GET_VAR 'j11: <root>.J<T1 of <root>.Outer, T1 of <root>.Outer> declared in <root>.Outer.<init>' type=<root>.J<T1 of <root>.Outer, T1 of <root>.Outer> origin=INITIALIZE_PROPERTY_FROM_PARAMETER
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-j11> visibility:public modality:FINAL <> ($this:<root>.Outer<T1 of <root>.Outer>) returnType:<root>.J<T1 of <root>.Outer, T1 of <root>.Outer>
correspondingProperty: PROPERTY name:j11 visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:<root>.Outer<T1 of <root>.Outer>
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-j11> (): <root>.J<T1 of <root>.Outer, T1 of <root>.Outer> declared in <root>.Outer'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:j11 type:<root>.J<T1 of <root>.Outer, T1 of <root>.Outer> visibility:private [final]' type=<root>.J<T1 of <root>.Outer, T1 of <root>.Outer> origin=null
receiver: GET_VAR '<this>: <root>.Outer<T1 of <root>.Outer> declared in <root>.Outer.<get-j11>' type=<root>.Outer<T1 of <root>.Outer> origin=null
CLASS CLASS name:Inner modality:FINAL visibility:public [inner] superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Outer.Inner<T2 of <root>.Outer.Inner, T1 of <root>.Outer>
TYPE_PARAMETER name:T2 index:0 variance: superTypes:[kotlin.Any?] reified:false
CONSTRUCTOR visibility:public <> ($this:<root>.Outer<T1 of <root>.Outer>, j12:<root>.J<T1 of <root>.Outer, T2 of <root>.Outer.Inner>) returnType:<root>.Outer.Inner<T2 of <root>.Outer.Inner, T1 of <root>.Outer> [primary]
$outer: VALUE_PARAMETER name:<this> type:<root>.Outer<T1 of <root>.Outer>
VALUE_PARAMETER name:j12 index:0 type:<root>.J<T1 of <root>.Outer, T2 of <root>.Outer.Inner>
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Inner modality:FINAL visibility:public [inner] superTypes:[kotlin.Any]'
PROPERTY name:j12 visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:j12 type:<root>.J<T1 of <root>.Outer, T2 of <root>.Outer.Inner> visibility:private [final]
EXPRESSION_BODY
GET_VAR 'j12: <root>.J<T1 of <root>.Outer, T2 of <root>.Outer.Inner> declared in <root>.Outer.Inner.<init>' type=<root>.J<T1 of <root>.Outer, T2 of <root>.Outer.Inner> origin=INITIALIZE_PROPERTY_FROM_PARAMETER
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-j12> visibility:public modality:FINAL <> ($this:<root>.Outer.Inner<T2 of <root>.Outer.Inner, T1 of <root>.Outer>) returnType:<root>.J<T1 of <root>.Outer, T2 of <root>.Outer.Inner>
correspondingProperty: PROPERTY name:j12 visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:<root>.Outer.Inner<T2 of <root>.Outer.Inner, T1 of <root>.Outer>
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-j12> (): <root>.J<T1 of <root>.Outer, T2 of <root>.Outer.Inner> declared in <root>.Outer.Inner'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:j12 type:<root>.J<T1 of <root>.Outer, T2 of <root>.Outer.Inner> visibility:private [final]' type=<root>.J<T1 of <root>.Outer, T2 of <root>.Outer.Inner> origin=null
receiver: GET_VAR '<this>: <root>.Outer.Inner<T2 of <root>.Outer.Inner, T1 of <root>.Outer> declared in <root>.Outer.Inner.<get-j12>' type=<root>.Outer.Inner<T2 of <root>.Outer.Inner, T1 of <root>.Outer> origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN name:test4 visibility:public modality:FINAL <> (f:kotlin.Function1<kotlin.String, kotlin.String>, g:kotlin.Function1<kotlin.Any, kotlin.String>) returnType:<root>.Outer.Inner<@[FlexibleNullability] kotlin.Any?, @[FlexibleNullability] kotlin.String?>
VALUE_PARAMETER name:f index:0 type:kotlin.Function1<kotlin.String, kotlin.String>
VALUE_PARAMETER name:g index:1 type:kotlin.Function1<kotlin.Any, kotlin.String>
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test4 (f: kotlin.Function1<kotlin.String, kotlin.String>, g: kotlin.Function1<kotlin.Any, kotlin.String>): <root>.Outer.Inner<@[FlexibleNullability] kotlin.Any?, @[FlexibleNullability] kotlin.String?> declared in <root>'
CONSTRUCTOR_CALL 'public constructor <init> (j12: <root>.J<T1 of <root>.Outer, T2 of <root>.Outer.Inner>) declared in <root>.Outer.Inner' type=<root>.Outer.Inner<@[FlexibleNullability] kotlin.Any?, @[FlexibleNullability] kotlin.String?> origin=null
<class: T2>: @[FlexibleNullability] kotlin.Any?
$outer: CONSTRUCTOR_CALL 'public constructor <init> (j11: <root>.J<T1 of <root>.Outer, T1 of <root>.Outer>) declared in <root>.Outer' type=<root>.Outer<@[FlexibleNullability] kotlin.String?> origin=null
<class: T1>: @[FlexibleNullability] kotlin.String?
j11: TYPE_OP type=<root>.J<@[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.String?> origin=SAM_CONVERSION typeOperand=<root>.J<@[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.String?>
GET_VAR 'f: kotlin.Function1<kotlin.String, kotlin.String> declared in <root>.test4' type=kotlin.Function1<kotlin.String, kotlin.String> origin=null
j12: TYPE_OP type=<root>.J<@[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.Any?> origin=SAM_CONVERSION typeOperand=<root>.J<@[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.Any?>
GET_VAR 'g: kotlin.Function1<kotlin.Any, kotlin.String> declared in <root>.test4' type=kotlin.Function1<kotlin.Any, kotlin.String> origin=null
FUN name:testGenericJavaCtor1 visibility:public modality:FINAL <> (f:kotlin.Function1<kotlin.String, kotlin.Int>) returnType:<root>.G<@[FlexibleNullability] kotlin.String?>
VALUE_PARAMETER name:f index:0 type:kotlin.Function1<kotlin.String, kotlin.Int>
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testGenericJavaCtor1 (f: kotlin.Function1<kotlin.String, kotlin.Int>): <root>.G<@[FlexibleNullability] kotlin.String?> declared in <root>'
CONSTRUCTOR_CALL 'public constructor <init> <TCtor> (x: @[FlexibleNullability] <root>.J<@[FlexibleNullability] TCtor of <root>.G.<init>?, @[FlexibleNullability] TClass of <root>.G?>?) declared in <root>.G' type=<root>.G<@[FlexibleNullability] kotlin.String?> origin=null
<class: TClass>: @[FlexibleNullability] kotlin.String?
<TCtor>: @[FlexibleNullability] kotlin.Int?
x: TYPE_OP type=<root>.J<@[FlexibleNullability] kotlin.Int?, @[FlexibleNullability] kotlin.String?> origin=SAM_CONVERSION typeOperand=<root>.J<@[FlexibleNullability] kotlin.Int?, @[FlexibleNullability] kotlin.String?>
GET_VAR 'f: kotlin.Function1<kotlin.String, kotlin.Int> declared in <root>.testGenericJavaCtor1' type=kotlin.Function1<kotlin.String, kotlin.Int> origin=null
FUN name:testGenericJavaCtor2 visibility:public modality:FINAL <> (x:kotlin.Any) returnType:kotlin.Unit
VALUE_PARAMETER name:x index:0 type:kotlin.Any
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
TYPE_OP type=kotlin.Function1<kotlin.String, kotlin.Int> origin=CAST typeOperand=kotlin.Function1<kotlin.String, kotlin.Int>
GET_VAR 'x: kotlin.Any declared in <root>.testGenericJavaCtor2' type=kotlin.Any origin=null
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CONSTRUCTOR_CALL 'public constructor <init> <TCtor> (x: @[FlexibleNullability] <root>.J<@[FlexibleNullability] TCtor of <root>.G.<init>?, @[FlexibleNullability] TClass of <root>.G?>?) declared in <root>.G' type=<root>.G<@[FlexibleNullability] kotlin.String?> origin=null
<class: TClass>: @[FlexibleNullability] kotlin.String?
<TCtor>: @[FlexibleNullability] kotlin.Int?
x: TYPE_OP type=<root>.J<@[FlexibleNullability] kotlin.Int?, @[FlexibleNullability] kotlin.String?> origin=SAM_CONVERSION typeOperand=<root>.J<@[FlexibleNullability] kotlin.Int?, @[FlexibleNullability] kotlin.String?>
TYPE_OP type=kotlin.Function1<kotlin.String, kotlin.Int> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<kotlin.String, kotlin.Int>
GET_VAR 'x: kotlin.Any declared in <root>.testGenericJavaCtor2' type=kotlin.Any origin=null
@@ -0,0 +1,42 @@
fun test3(f1: Function1<String, String>, f2: Function1<Int, String>): D<@FlexibleNullability Int?, @FlexibleNullability String?> {
return C<@FlexibleNullability String?>(jxx = f1 /*-> J<@FlexibleNullability String?, @FlexibleNullability String?> */).D<@FlexibleNullability Int?>(jxy = f2 /*-> J<@FlexibleNullability String?, @FlexibleNullability Int?> */)
}
class Outer<T1 : Any?> {
constructor(j11: J<T1, T1>) /* primary */ {
super/*Any*/()
/* <init>() */
}
val j11: J<T1, T1>
field = j11
get
inner class Inner<T2 : Any?> {
constructor(j12: J<T1, T2>) /* primary */ {
super/*Any*/()
/* <init>() */
}
val j12: J<T1, T2>
field = j12
get
}
}
fun test4(f: Function1<String, String>, g: Function1<Any, String>): Inner<@FlexibleNullability Any?, @FlexibleNullability String?> {
return Outer<@FlexibleNullability String?>(j11 = f /*-> J<@FlexibleNullability String?, @FlexibleNullability String?> */).Inner<@FlexibleNullability Any?>(j12 = g /*-> J<@FlexibleNullability String?, @FlexibleNullability Any?> */)
}
fun testGenericJavaCtor1(f: Function1<String, Int>): G<@FlexibleNullability String?> {
return G<@FlexibleNullability String?, @FlexibleNullability Int?>(x = f /*-> J<@FlexibleNullability Int?, @FlexibleNullability String?> */)
}
fun testGenericJavaCtor2(x: Any) {
x as Function1<String, Int> /*~> Unit */
G<@FlexibleNullability String?, @FlexibleNullability Int?>(x = x /*as Function1<String, Int> */ /*-> J<@FlexibleNullability Int?, @FlexibleNullability String?> */) /*~> Unit */
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// TARGET_BACKEND: JVM
// FILE: samConversionInGenericConstructorCall.kt
@@ -40,3 +40,4 @@ fun testGenericJavaCtor2(x: Any) {
x as Function1<String, Int> /*~> Unit */
G<@FlexibleNullability String?, @FlexibleNullability Int?>(x = x /*as Function1<String, Int> */ /*-> @FlexibleNullability J<@FlexibleNullability Int?, @FlexibleNullability String?>? */) /*~> Unit */
}
@@ -24,7 +24,7 @@ FILE fqName:<root> fileName:/samConversionToGeneric.kt
RETURN type=kotlin.Nothing from='public final fun test3 (): kotlin.Unit declared in <root>'
CALL 'public open fun bar <X> (j: @[FlexibleNullability] <root>.J<@[FlexibleNullability] X of <root>.H.bar?>?): kotlin.Unit declared in <root>.H' type=kotlin.Unit origin=null
<X>: @[FlexibleNullability] kotlin.String?
j: TYPE_OP type=@[FlexibleNullability] <root>.J<@[FlexibleNullability] kotlin.String?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] <root>.J<@[FlexibleNullability] kotlin.String?>?
j: TYPE_OP type=<root>.J<@[FlexibleNullability] kotlin.String?> origin=SAM_CONVERSION typeOperand=<root>.J<@[FlexibleNullability] kotlin.String?>
FUN_EXPR type=kotlin.Function1<kotlin.String, @[FlexibleNullability] kotlin.String?> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (x:kotlin.String) returnType:@[FlexibleNullability] kotlin.String?
VALUE_PARAMETER name:x index:0 type:kotlin.String
@@ -49,7 +49,7 @@ FILE fqName:<root> fileName:/samConversionToGeneric.kt
GET_VAR 'a: kotlin.Any declared in <root>.test5' type=kotlin.Any origin=null
CALL 'public open fun bar <X> (j: @[FlexibleNullability] <root>.J<@[FlexibleNullability] X of <root>.H.bar?>?): kotlin.Unit declared in <root>.H' type=kotlin.Unit origin=null
<X>: @[FlexibleNullability] kotlin.String?
j: TYPE_OP type=@[FlexibleNullability] <root>.J<@[FlexibleNullability] kotlin.String?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] <root>.J<@[FlexibleNullability] kotlin.String?>?
j: TYPE_OP type=<root>.J<@[FlexibleNullability] kotlin.String?> origin=SAM_CONVERSION typeOperand=<root>.J<@[FlexibleNullability] kotlin.String?>
TYPE_OP type=kotlin.Function1<kotlin.String, kotlin.String> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<kotlin.String, kotlin.String>
GET_VAR 'a: kotlin.Any declared in <root>.test5' type=kotlin.Any origin=null
FUN name:test6 visibility:public modality:FINAL <T> (a:kotlin.Function1<T of <root>.test6, T of <root>.test6>) returnType:kotlin.Unit
@@ -58,7 +58,7 @@ FILE fqName:<root> fileName:/samConversionToGeneric.kt
BLOCK_BODY
CALL 'public open fun bar <X> (j: @[FlexibleNullability] <root>.J<@[FlexibleNullability] X of <root>.H.bar?>?): kotlin.Unit declared in <root>.H' type=kotlin.Unit origin=null
<X>: @[FlexibleNullability] T of <root>.test6?
j: TYPE_OP type=@[FlexibleNullability] <root>.J<@[FlexibleNullability] T of <root>.test6?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] <root>.J<@[FlexibleNullability] T of <root>.test6?>?
j: TYPE_OP type=<root>.J<@[FlexibleNullability] T of <root>.test6?> origin=SAM_CONVERSION typeOperand=<root>.J<@[FlexibleNullability] T of <root>.test6?>
GET_VAR 'a: kotlin.Function1<T of <root>.test6, T of <root>.test6> declared in <root>.test6' type=kotlin.Function1<T of <root>.test6, T of <root>.test6> origin=null
FUN name:test7 visibility:public modality:FINAL <T> (a:kotlin.Any) returnType:kotlin.Unit
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] reified:false
@@ -69,7 +69,7 @@ FILE fqName:<root> fileName:/samConversionToGeneric.kt
GET_VAR 'a: kotlin.Any declared in <root>.test7' type=kotlin.Any origin=null
CALL 'public open fun bar <X> (j: @[FlexibleNullability] <root>.J<@[FlexibleNullability] X of <root>.H.bar?>?): kotlin.Unit declared in <root>.H' type=kotlin.Unit origin=null
<X>: @[FlexibleNullability] T of <root>.test7?
j: TYPE_OP type=@[FlexibleNullability] <root>.J<@[FlexibleNullability] T of <root>.test7?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] <root>.J<@[FlexibleNullability] T of <root>.test7?>?
j: TYPE_OP type=<root>.J<@[FlexibleNullability] T of <root>.test7?> origin=SAM_CONVERSION typeOperand=<root>.J<@[FlexibleNullability] T of <root>.test7?>
TYPE_OP type=kotlin.Function1<T of <root>.test7, T of <root>.test7> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<T of <root>.test7, T of <root>.test7>
GET_VAR 'a: kotlin.Any declared in <root>.test7' type=kotlin.Any origin=null
FUN name:test8 visibility:public modality:FINAL <> (efn:@[ExtensionFunctionType] kotlin.Function1<kotlin.String, kotlin.String>) returnType:<root>.J<@[FlexibleNullability] kotlin.String?>
@@ -83,12 +83,12 @@ FILE fqName:<root> fileName:/samConversionToGeneric.kt
BLOCK_BODY
CALL 'public open fun bar <X> (j: @[FlexibleNullability] <root>.J<@[FlexibleNullability] X of <root>.H.bar?>?): kotlin.Unit declared in <root>.H' type=kotlin.Unit origin=null
<X>: @[FlexibleNullability] kotlin.String?
j: TYPE_OP type=@[FlexibleNullability] <root>.J<@[FlexibleNullability] kotlin.String?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] <root>.J<@[FlexibleNullability] kotlin.String?>?
j: TYPE_OP type=<root>.J<@[FlexibleNullability] kotlin.String?> origin=SAM_CONVERSION typeOperand=<root>.J<@[FlexibleNullability] kotlin.String?>
GET_VAR 'efn: @[ExtensionFunctionType] kotlin.Function1<kotlin.String, kotlin.String> declared in <root>.test9' type=@[ExtensionFunctionType] kotlin.Function1<kotlin.String, kotlin.String> origin=null
FUN name:test10 visibility:public modality:FINAL <> (fn:kotlin.Function1<kotlin.Int, kotlin.String>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:kotlin.Function1<kotlin.Int, kotlin.String>
BLOCK_BODY
CALL 'public open fun bar2x <Y> (j2x: @[FlexibleNullability] <root>.J2X<@[FlexibleNullability] Y of <root>.H.bar2x?>?): kotlin.Unit declared in <root>.H' type=kotlin.Unit origin=null
<Y>: @[FlexibleNullability] kotlin.Int?
j2x: TYPE_OP type=@[FlexibleNullability] <root>.J2X<@[FlexibleNullability] kotlin.Int?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] <root>.J2X<@[FlexibleNullability] kotlin.Int?>?
j2x: TYPE_OP type=<root>.J2X<@[FlexibleNullability] kotlin.Int?> origin=SAM_CONVERSION typeOperand=<root>.J2X<@[FlexibleNullability] kotlin.Int?>
GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.String> declared in <root>.test10' type=kotlin.Function1<kotlin.Int, kotlin.String> origin=null
@@ -16,7 +16,7 @@ fun test3() {
return bar<@FlexibleNullability String?>(j = local fun <anonymous>(x: String): @FlexibleNullability String? {
return x
}
/*-> @FlexibleNullability J<@FlexibleNullability String?>? */)
/*-> J<@FlexibleNullability String?> */)
}
fun test4(a: Any) {
@@ -26,16 +26,16 @@ fun test4(a: Any) {
fun test5(a: Any) {
a as Function1<String, String> /*~> Unit */
bar<@FlexibleNullability String?>(j = a /*as Function1<String, String> */ /*-> @FlexibleNullability J<@FlexibleNullability String?>? */)
bar<@FlexibleNullability String?>(j = a /*as Function1<String, String> */ /*-> J<@FlexibleNullability String?> */)
}
fun <T : Any?> test6(a: Function1<T, T>) {
bar<@FlexibleNullability T?>(j = a /*-> @FlexibleNullability J<@FlexibleNullability T?>? */)
bar<@FlexibleNullability T?>(j = a /*-> J<@FlexibleNullability T?> */)
}
fun <T : Any?> test7(a: Any) {
a as Function1<T, T> /*~> Unit */
bar<@FlexibleNullability T?>(j = a /*as Function1<T, T> */ /*-> @FlexibleNullability J<@FlexibleNullability T?>? */)
bar<@FlexibleNullability T?>(j = a /*as Function1<T, T> */ /*-> J<@FlexibleNullability T?> */)
}
fun test8(efn: @ExtensionFunctionType Function1<String, String>): J<@FlexibleNullability String?> {
@@ -43,9 +43,9 @@ fun test8(efn: @ExtensionFunctionType Function1<String, String>): J<@FlexibleNul
}
fun test9(efn: @ExtensionFunctionType Function1<String, String>) {
bar<@FlexibleNullability String?>(j = efn /*-> @FlexibleNullability J<@FlexibleNullability String?>? */)
bar<@FlexibleNullability String?>(j = efn /*-> J<@FlexibleNullability String?> */)
}
fun test10(fn: Function1<Int, String>) {
bar2x<@FlexibleNullability Int?>(j2x = fn /*-> @FlexibleNullability J2X<@FlexibleNullability Int?>? */)
bar2x<@FlexibleNullability Int?>(j2x = fn /*-> J2X<@FlexibleNullability Int?> */)
}
@@ -0,0 +1,54 @@
FILE fqName:<root> fileName:/samConversions.kt
FUN name:test0 visibility:public modality:FINAL <> ($receiver:<root>.J, a:java.lang.Runnable) returnType:kotlin.Unit
$receiver: VALUE_PARAMETER name:<this> type:<root>.J
VALUE_PARAMETER name:a index:0 type:java.lang.Runnable
BLOCK_BODY
CALL 'public open fun runStatic (r: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
r: GET_VAR 'a: java.lang.Runnable declared in <root>.test0' type=java.lang.Runnable origin=null
CALL 'public open fun runIt (r: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.J declared in <root>.test0' type=<root>.J origin=null
r: GET_VAR 'a: java.lang.Runnable declared in <root>.test0' type=java.lang.Runnable origin=null
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
CALL 'public open fun runStatic (r: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
r: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
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
CALL 'public final fun test1 (): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
FUN name:test2 visibility:public modality:FINAL <> ($receiver:<root>.J) returnType:kotlin.Unit
$receiver: VALUE_PARAMETER name:<this> type:<root>.J
BLOCK_BODY
CALL 'public open fun runIt (r: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.J declared in <root>.test2' type=<root>.J origin=null
r: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
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
CALL 'public final fun test1 (): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
FUN name:test3 visibility:public modality:FINAL <> ($receiver:<root>.J, a:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit
$receiver: VALUE_PARAMETER name:<this> type:<root>.J
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit>
BLOCK_BODY
CALL 'public open fun run2 (r1: @[FlexibleNullability] java.lang.Runnable?, r2: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.J declared in <root>.test3' type=<root>.J origin=null
r1: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
GET_VAR 'a: kotlin.Function0<kotlin.Unit> declared in <root>.test3' type=kotlin.Function0<kotlin.Unit> origin=null
r2: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
GET_VAR 'a: kotlin.Function0<kotlin.Unit> declared in <root>.test3' type=kotlin.Function0<kotlin.Unit> origin=null
FUN name:test4 visibility:public modality:FINAL <> ($receiver:<root>.J, a:kotlin.Function0<kotlin.Unit>, b:kotlin.Function0<kotlin.Unit>, flag:kotlin.Boolean) returnType:kotlin.Unit
$receiver: VALUE_PARAMETER name:<this> type:<root>.J
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit>
VALUE_PARAMETER name:b index:1 type:kotlin.Function0<kotlin.Unit>
VALUE_PARAMETER name:flag index:2 type:kotlin.Boolean
BLOCK_BODY
CALL 'public open fun runIt (r: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.J declared in <root>.test4' type=<root>.J origin=null
r: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
WHEN type=kotlin.Function0<kotlin.Unit> origin=IF
BRANCH
if: GET_VAR 'flag: kotlin.Boolean declared in <root>.test4' type=kotlin.Boolean origin=null
then: GET_VAR 'a: kotlin.Function0<kotlin.Unit> declared in <root>.test4' type=kotlin.Function0<kotlin.Unit> origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'b: kotlin.Function0<kotlin.Unit> declared in <root>.test4' type=kotlin.Function0<kotlin.Unit> origin=null
@@ -0,0 +1,29 @@
fun J.test0(a: Runnable) {
runStatic(r = a)
<this>.runIt(r = a)
}
fun test1() {
runStatic(r = local fun <anonymous>() {
test1()
}
/*-> Runnable */)
}
fun J.test2() {
<this>.runIt(r = local fun <anonymous>() {
test1()
}
/*-> Runnable */)
}
fun J.test3(a: Function0<Unit>) {
<this>.run2(r1 = a /*-> Runnable */, r2 = a /*-> Runnable */)
}
fun J.test4(a: Function0<Unit>, b: Function0<Unit>, flag: Boolean) {
<this>.runIt(r = when {
flag -> a
else -> b
} /*-> Runnable */)
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// TARGET_BACKEND: JVM
// WITH_JDK
@@ -27,3 +27,4 @@ fun J.test4(a: Function0<Unit>, b: Function0<Unit>, flag: Boolean) {
else -> b
} /*-> @FlexibleNullability Runnable? */)
}
@@ -49,7 +49,7 @@ FILE fqName:<root> fileName:/samConversionsWithSmartCasts.kt
$this: CONSTRUCTOR_CALL 'public constructor <init> () declared in <root>.J' type=<root>.J origin=null
r1: TYPE_OP type=java.lang.Runnable origin=IMPLICIT_CAST typeOperand=java.lang.Runnable
GET_VAR 'a: kotlin.Function0<kotlin.Unit> declared in <root>.test4' type=kotlin.Function0<kotlin.Unit> origin=null
r2: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable?
r2: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
GET_VAR 'b: kotlin.Function0<kotlin.Unit> declared in <root>.test4' type=kotlin.Function0<kotlin.Unit> origin=null
FUN name:test5 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit
VALUE_PARAMETER name:a index:0 type:kotlin.Any
@@ -87,7 +87,7 @@ FILE fqName:<root> fileName:/samConversionsWithSmartCasts.kt
GET_VAR 'a: kotlin.Any declared in <root>.test6' type=kotlin.Any origin=null
CALL 'public open fun run1 (r: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
$this: CONSTRUCTOR_CALL 'public constructor <init> () declared in <root>.J' type=<root>.J origin=null
r: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable?
r: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function0<kotlin.Unit>
GET_VAR 'a: kotlin.Any declared in <root>.test6' type=kotlin.Any origin=null
FUN name:test7 visibility:public modality:FINAL <> (a:kotlin.Function1<kotlin.Int, kotlin.Int>) returnType:kotlin.Unit
@@ -98,7 +98,7 @@ FILE fqName:<root> fileName:/samConversionsWithSmartCasts.kt
GET_VAR 'a: kotlin.Function1<kotlin.Int, kotlin.Int> declared in <root>.test7' type=kotlin.Function1<kotlin.Int, kotlin.Int> origin=null
CALL 'public open fun run1 (r: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
$this: CONSTRUCTOR_CALL 'public constructor <init> () declared in <root>.J' type=<root>.J origin=null
r: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable?
r: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
GET_VAR 'a: kotlin.Function1<kotlin.Int, kotlin.Int> declared in <root>.test7' type=kotlin.Function1<kotlin.Int, kotlin.Int> origin=null
FUN name:test8 visibility:public modality:FINAL <> (a:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit>
@@ -113,5 +113,5 @@ FILE fqName:<root> fileName:/samConversionsWithSmartCasts.kt
BLOCK_BODY
CALL 'public open fun run1 (r: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
$this: CONSTRUCTOR_CALL 'public constructor <init> () declared in <root>.J' type=<root>.J origin=null
r: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable?
r: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
FUNCTION_REFERENCE 'public final fun test9 (): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null reflectionTarget=<same>
@@ -25,7 +25,7 @@ fun test3(a: Function0<Unit>) {
fun test4(a: Function0<Unit>, b: Function0<Unit>) {
when {
a is Runnable -> { // BLOCK
J().run2(r1 = a /*as Runnable */, r2 = b /*-> @FlexibleNullability Runnable? */)
J().run2(r1 = a /*as Runnable */, r2 = b /*-> Runnable */)
}
}
}
@@ -49,12 +49,12 @@ fun test5x(a: Any) {
fun test6(a: Any) {
a as Function0<Unit> /*~> Unit */
J().run1(r = a /*as Function0<Unit> */ /*-> @FlexibleNullability Runnable? */)
J().run1(r = a /*as Function0<Unit> */ /*-> Runnable */)
}
fun test7(a: Function1<Int, Int>) {
a as Function0<Unit> /*~> Unit */
J().run1(r = a /*-> @FlexibleNullability Runnable? */)
J().run1(r = a /*-> Runnable */)
}
fun test8(a: Function0<Unit>) {
@@ -62,6 +62,5 @@ fun test8(a: Function0<Unit>) {
}
fun test9() {
J().run1(r = ::test9 /*-> @FlexibleNullability Runnable? */)
J().run1(r = ::test9 /*-> Runnable */)
}
@@ -6,39 +6,39 @@ FILE fqName:<root> fileName:/samOperators.kt
BLOCK_BODY
CALL 'public open fun get (k: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.J declared in <root>.test1' type=<root>.J origin=null
k: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable?
k: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
FUNCTION_REFERENCE 'public final fun f (): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null reflectionTarget=<same>
CALL 'public open fun get (k: @[FlexibleNullability] java.lang.Runnable?, m: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.J declared in <root>.test1' type=<root>.J origin=null
k: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable?
k: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
FUNCTION_REFERENCE 'public final fun f (): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null reflectionTarget=<same>
m: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable?
m: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
FUNCTION_REFERENCE 'public final fun f (): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null reflectionTarget=<same>
FUN name:test2 visibility:public modality:FINAL <> ($receiver:<root>.J) returnType:kotlin.Unit
$receiver: VALUE_PARAMETER name:<this> type:<root>.J
BLOCK_BODY
CALL 'public open fun set (k: @[FlexibleNullability] java.lang.Runnable?, v: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.J declared in <root>.test2' type=<root>.J origin=null
k: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable?
k: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
FUNCTION_REFERENCE 'public final fun f (): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null reflectionTarget=<same>
v: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable?
v: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
FUNCTION_REFERENCE 'public final fun f (): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null reflectionTarget=<same>
CALL 'public open fun set (k: @[FlexibleNullability] java.lang.Runnable?, m: @[FlexibleNullability] java.lang.Runnable?, v: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.J declared in <root>.test2' type=<root>.J origin=null
k: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable?
k: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
FUNCTION_REFERENCE 'public final fun f (): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null reflectionTarget=<same>
m: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable?
m: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
FUNCTION_REFERENCE 'public final fun f (): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null reflectionTarget=<same>
v: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable?
v: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
FUNCTION_REFERENCE 'public final fun f (): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null reflectionTarget=<same>
FUN name:test3 visibility:public modality:FINAL <> ($receiver:<root>.J) returnType:kotlin.Unit
$receiver: VALUE_PARAMETER name:<this> type:<root>.J
BLOCK_BODY
CALL 'public open fun plusAssign (i: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=PLUSEQ
$this: GET_VAR '<this>: <root>.J declared in <root>.test3' type=<root>.J origin=null
i: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable?
i: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
FUNCTION_REFERENCE 'public final fun f (): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null reflectionTarget=<same>
CALL 'public open fun minusAssign (i: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=MINUSEQ
$this: GET_VAR '<this>: <root>.J declared in <root>.test3' type=<root>.J origin=null
i: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable?
i: TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable
FUNCTION_REFERENCE 'public final fun f (): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null reflectionTarget=<same>
@@ -2,16 +2,16 @@ fun f() {
}
fun J.test1() {
<this>.get(k = ::f /*-> @FlexibleNullability Runnable? */)
<this>.get(k = ::f /*-> @FlexibleNullability Runnable? */, m = ::f /*-> @FlexibleNullability Runnable? */)
<this>.get(k = ::f /*-> Runnable */)
<this>.get(k = ::f /*-> Runnable */, m = ::f /*-> Runnable */)
}
fun J.test2() {
<this>.set(k = ::f /*-> @FlexibleNullability Runnable? */, v = ::f /*-> @FlexibleNullability Runnable? */)
<this>.set(k = ::f /*-> @FlexibleNullability Runnable? */, m = ::f /*-> @FlexibleNullability Runnable? */, v = ::f /*-> @FlexibleNullability Runnable? */)
<this>.set(k = ::f /*-> Runnable */, v = ::f /*-> Runnable */)
<this>.set(k = ::f /*-> Runnable */, m = ::f /*-> Runnable */, v = ::f /*-> Runnable */)
}
fun J.test3() {
<this>.plusAssign(i = ::f /*-> @FlexibleNullability Runnable? */)
<this>.minusAssign(i = ::f /*-> @FlexibleNullability Runnable? */)
<this>.plusAssign(i = ::f /*-> Runnable */)
<this>.minusAssign(i = ::f /*-> Runnable */)
}
+1 -1
View File
@@ -17,7 +17,7 @@ FILE fqName:<root> fileName:/test.kt
CALL 'public open fun computeIfAbsent (p0: @[EnhancedNullability] K of kotlin.collections.MutableMap, p1: @[EnhancedNullability] java.util.function.Function<in @[EnhancedNullability] K of kotlin.collections.MutableMap, out @[EnhancedNullability] V of kotlin.collections.MutableMap>): @[EnhancedNullability] V of kotlin.collections.MutableMap declared in kotlin.collections.MutableMap' type=@[EnhancedNullability] kotlin.String origin=null
$this: GET_VAR 'val map: kotlin.collections.MutableMap<<root>.Fun, kotlin.String> declared in <root>.box' type=kotlin.collections.MutableMap<<root>.Fun, kotlin.String> origin=null
p0: GET_VAR 'val fn: <root>.Fun declared in <root>.box' type=<root>.Fun origin=null
p1: TYPE_OP type=@[EnhancedNullability] java.util.function.Function<kotlin.Any?, @[EnhancedNullability] kotlin.String> origin=SAM_CONVERSION typeOperand=@[EnhancedNullability] java.util.function.Function<kotlin.Any?, @[EnhancedNullability] kotlin.String>
p1: TYPE_OP type=java.util.function.Function<kotlin.Any?, @[EnhancedNullability] kotlin.String> origin=SAM_CONVERSION typeOperand=java.util.function.Function<kotlin.Any?, @[EnhancedNullability] kotlin.String>
TYPE_OP type=kotlin.Function1<@[EnhancedNullability] kotlin.Any?, @[EnhancedNullability] kotlin.String> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<@[EnhancedNullability] kotlin.Any?, @[EnhancedNullability] kotlin.String>
FUN_EXPR type=kotlin.Function1<@[EnhancedNullability] <root>.Fun, @[EnhancedNullability] kotlin.String> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:@[EnhancedNullability] <root>.Fun) returnType:@[EnhancedNullability] kotlin.String
+1 -1
View File
@@ -7,5 +7,5 @@ fun box(): String {
return map.computeIfAbsent(p0 = fn, p1 = local fun <anonymous>(it: @EnhancedNullability Fun): @EnhancedNullability String {
return "OK"
}
/*as Function1<@EnhancedNullability Any?, @EnhancedNullability String> */ /*-> @EnhancedNullability Function<Any?, @EnhancedNullability String> */) /*!! String */
/*as Function1<@EnhancedNullability Any?, @EnhancedNullability String> */ /*-> Function<Any?, @EnhancedNullability String> */) /*!! String */
}
@@ -46831,6 +46831,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/sam/kt59858.kt");
}
@Test
@TestMetadata("noConversionFromSamToSam.kt")
public void testNoConversionFromSamToSam() throws Exception {
runTest("compiler/testData/codegen/box/sam/noConversionFromSamToSam.kt");
}
@Test
@TestMetadata("nonInlinedSamWrapper.kt")
public void testNonInlinedSamWrapper() throws Exception {
@@ -49813,6 +49813,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/sam/kt59858.kt");
}
@Test
@TestMetadata("noConversionFromSamToSam.kt")
public void testNoConversionFromSamToSam() throws Exception {
runTest("compiler/testData/codegen/box/sam/noConversionFromSamToSam.kt");
}
@Test
@TestMetadata("nonInlinedSamWrapper.kt")
public void testNonInlinedSamWrapper() throws Exception {
@@ -49813,6 +49813,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
runTest("compiler/testData/codegen/box/sam/kt59858.kt");
}
@Test
@TestMetadata("noConversionFromSamToSam.kt")
public void testNoConversionFromSamToSam() throws Exception {
runTest("compiler/testData/codegen/box/sam/noConversionFromSamToSam.kt");
}
@Test
@TestMetadata("nonInlinedSamWrapper.kt")
public void testNonInlinedSamWrapper() throws Exception {
@@ -40003,6 +40003,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/sam/kt59858.kt");
}
@TestMetadata("noConversionFromSamToSam.kt")
public void testNoConversionFromSamToSam() throws Exception {
runTest("compiler/testData/codegen/box/sam/noConversionFromSamToSam.kt");
}
@TestMetadata("nonInlinedSamWrapper.kt")
public void testNonInlinedSamWrapper() throws Exception {
runTest("compiler/testData/codegen/box/sam/nonInlinedSamWrapper.kt");