diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index c40ff51d6fb..be38e5c294b 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -168,7 +168,8 @@ class Fir2IrDeclarationStorage( isData = regularClass?.isData == true, isExternal = regularClass?.isExternal == true, isInline = regularClass?.isInline == true, - isExpect = regularClass?.isExpect == true + isExpect = regularClass?.isExpect == true, + isFun = false // TODO FirRegularClass.isFun ).apply { descriptor.bind(this) if (setParent && regularClass != null) { @@ -216,7 +217,7 @@ class Fir2IrDeclarationStorage( Name.special(""), anonymousObject.classKind, Visibilities.LOCAL, modality, isCompanion = false, isInner = false, isData = false, - isExternal = false, isInline = false, isExpect = false + isExternal = false, isInline = false, isExpect = false, isFun = false ).apply { descriptor.bind(this) declareThisReceiver() @@ -236,7 +237,7 @@ class Fir2IrDeclarationStorage( enumEntry.name, anonymousObject.classKind, Visibilities.LOCAL, modality, isCompanion = false, isInner = false, isData = false, - isExternal = false, isInline = false, isExpect = false + isExternal = false, isInline = false, isExpect = false, isFun = false ).apply { descriptor.bind(this) declareThisReceiver() diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java index 84daeaeca1e..280503b34d7 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java @@ -1420,6 +1420,39 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { } } + @TestMetadata("compiler/testData/ir/irText/expressions/funInterface") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class FunInterface extends AbstractFir2IrTextTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.ANY, testDataFilePath, "// IGNORE_BACKEND_FIR: "); + } + + public void testAllFilesPresentInFunInterface() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irText/expressions/funInterface"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("basicFunInterfaceConversion.kt") + public void testBasicFunInterfaceConversion() throws Exception { + runTest("compiler/testData/ir/irText/expressions/funInterface/basicFunInterfaceConversion.kt"); + } + + @TestMetadata("castFromAny.kt") + public void testCastFromAny() throws Exception { + runTest("compiler/testData/ir/irText/expressions/funInterface/castFromAny.kt"); + } + + @TestMetadata("partialSam.kt") + public void testPartialSam() throws Exception { + runTest("compiler/testData/ir/irText/expressions/funInterface/partialSam.kt"); + } + + @TestMetadata("samConversionsWithSmartCasts.kt") + public void testSamConversionsWithSmartCasts() throws Exception { + runTest("compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.kt"); + } + } + @TestMetadata("compiler/testData/ir/irText/expressions/sam") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AbstractSuspendFunctionsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AbstractSuspendFunctionsLowering.kt index a9339f691bd..5521bcb25f0 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AbstractSuspendFunctionsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AbstractSuspendFunctionsLowering.kt @@ -294,7 +294,8 @@ abstract class AbstractSuspendFunctionsLowering(val co isData = false, isExternal = false, isInline = false, - isExpect = false + isExpect = false, + isFun = false ).apply { d.bind(this) parent = irFunction.parent diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt index 3448e6420f3..8e7545f8340 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt @@ -5,10 +5,9 @@ package org.jetbrains.kotlin.ir.builders.declarations -import org.jetbrains.kotlin.backend.common.descriptors.* +import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.* import org.jetbrains.kotlin.ir.descriptors.* @@ -27,7 +26,7 @@ fun IrClassBuilder.buildClass(): IrClass { IrClassSymbolImpl(wrappedDescriptor), name, kind, visibility, modality, isCompanion = isCompanion, isInner = isInner, isData = isData, isExternal = isExternal, - isInline = isInline, isExpect = isExpect + isInline = isInline, isExpect = isExpect, isFun = isFun ).also { wrappedDescriptor.bind(it) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt index 2d3649ec63e..e051a448181 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt @@ -127,7 +127,7 @@ class JsSharedVariablesManager(val builtIns: IrBuiltIns, val implicitDeclaration UNDEFINED_OFFSET, UNDEFINED_OFFSET, JsLoweredDeclarationOrigin.JS_CLOSURE_BOX_CLASS_DECLARATION, IrClassSymbolImpl(descriptor), Name.identifier(boxTypeName), ClassKind.CLASS, Visibilities.PUBLIC, Modality.FINAL, isCompanion = false, isInner = false, isData = false, isExternal = false, - isInline = false, isExpect = false + isInline = false, isExpect = false, isFun = false ) descriptor.bind(declaration) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt index b8e68308261..4f3121f515e 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt @@ -58,8 +58,8 @@ class JvmGeneratorExtensions(private val generateFacades: Boolean = true) : Gene } override fun getSubstitutedFunctionTypeForSamType(samType: KotlinType): KotlinType { - val descriptor = samType.constructor.declarationDescriptor as? JavaClassDescriptor - ?: throw AssertionError("SAM should be represented by a Java class: $samType") + val descriptor = samType.constructor.declarationDescriptor as? ClassDescriptor + ?: throw AssertionError("SAM should be represented by a class: $samType") val singleAbstractMethod = getSingleAbstractMethodOrNull(descriptor) ?: throw AssertionError("$descriptor should have a single abstract method") val unsubstitutedFunctionType = getFunctionTypeForAbstractMethod(singleAbstractMethod, false) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt index 6e5b5c29406..484dbdce7e0 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt @@ -236,7 +236,8 @@ class JvmDeclarationFactory( isData = false, isExternal = false, isInline = false, - isExpect = false + isExpect = false, + isFun = false ).apply { descriptor.bind(this) parent = interfaceClass diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt index d725431e104..5654a32a28c 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt @@ -88,7 +88,8 @@ private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPa isData = false, isExternal = false, isInline = false, - isExpect = false + isExpect = false, + isFun = false ).apply { descriptor.bind(this) superTypes.add(context.irBuiltIns.anyType) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrClassBuilder.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrClassBuilder.kt index 67a9e37ad54..c5b1f03788a 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrClassBuilder.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrClassBuilder.kt @@ -32,5 +32,6 @@ class IrClassBuilder : IrDeclarationBuilder() { isExternal = from.isExternal isInline = from.isInline isExpect = from.isExpect + isFun = from.isFun } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt index d0d9eacdcea..65a20c8fd3e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt @@ -39,6 +39,7 @@ interface IrClass : val isExternal: Boolean val isInline: Boolean val isExpect: Boolean + val isFun: Boolean val superTypes: MutableList diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt index e17bfd8ea8d..cd6eb0de4bd 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt @@ -44,7 +44,8 @@ class IrClassImpl( override val isData: Boolean, override val isExternal: Boolean, override val isInline: Boolean, - override val isExpect: Boolean + override val isExpect: Boolean, + override val isFun: Boolean ) : IrDeclarationBase(startOffset, endOffset, origin), IrClass { @@ -66,7 +67,8 @@ class IrClassImpl( isData = symbol.descriptor.isData, isExternal = symbol.descriptor.isEffectivelyExternal(), isInline = symbol.descriptor.isInline, - isExpect = symbol.descriptor.isExpect + isExpect = symbol.descriptor.isExpect, + isFun = symbol.descriptor.isFun ) init { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyClass.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyClass.kt index c4dac814a3d..1222fc0d2b3 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyClass.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyClass.kt @@ -35,6 +35,7 @@ class IrLazyClass( override val isExternal: Boolean, override val isInline: Boolean, override val isExpect: Boolean, + override val isFun: Boolean, stubGenerator: DeclarationStubGenerator, typeTranslator: TypeTranslator ) : @@ -59,6 +60,7 @@ class IrLazyClass( isExternal = symbol.descriptor.isEffectivelyExternal(), isInline = symbol.descriptor.isInline, isExpect = symbol.descriptor.isExpect, + isFun = symbol.descriptor.isFun, stubGenerator = stubGenerator, typeTranslator = TypeTranslator ) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt index 1430cdbe878..4a7b6c44122 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt @@ -142,12 +142,13 @@ open class DeepCopyIrTreeWithSymbols( declaration.kind, declaration.visibility, declaration.modality, - declaration.isCompanion, - declaration.isInner, - declaration.isData, - declaration.isExternal, - declaration.isInline, - declaration.isExpect + isCompanion = declaration.isCompanion, + isInner = declaration.isInner, + isData = declaration.isData, + isExternal = declaration.isExternal, + isInline = declaration.isInline, + isExpect = declaration.isExpect, + isFun = declaration.isFun ).apply { transformAnnotations(declaration) copyTypeParametersFrom(declaration) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt index 94a28b9e0ae..92cc9186eff 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt @@ -462,7 +462,8 @@ class RenderIrElementVisitor(private val normalizeNames: Boolean = false) : IrEl "data".takeIf { isData }, "external".takeIf { isExternal }, "inline".takeIf { isInline }, - "expect".takeIf { isExpect } + "expect".takeIf { isExpect }, + "fun".takeIf { isFun } ) override fun visitVariable(declaration: IrVariable, data: Nothing?): String = diff --git a/compiler/ir/serialization.common/src/KotlinIr.proto b/compiler/ir/serialization.common/src/KotlinIr.proto index 8d8aa973990..6afeab3fbaa 100644 --- a/compiler/ir/serialization.common/src/KotlinIr.proto +++ b/compiler/ir/serialization.common/src/KotlinIr.proto @@ -648,6 +648,7 @@ message IrClass { required IrDeclarationContainer declaration_container = 13; repeated int32 super_type = 14; required bool is_expect = 15; + required bool is_fun = 16; } message IrTypeAlias { diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt index 3810546e4a7..5ed26eb9863 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt @@ -980,7 +980,8 @@ abstract class IrFileDeserializer( isData = proto.isData, isExternal = proto.isExternal, isInline = proto.isInline, - isExpect = proto.isExpect + isExpect = proto.isExpect, + isFun = proto.isFun ) }.usingParent { proto.declarationContainer.declarationList.mapTo(declarations) { deserializeDeclaration(it) } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt index a2c249bfb50..3d123c0c20e 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt @@ -1198,6 +1198,7 @@ open class IrFileSerializer( .setIsExternal(clazz.isExternal) .setIsInline(clazz.isInline) .setIsExpect(clazz.isExpect) + .setIsFun(clazz.isFun) .setTypeParameters(serializeIrTypeParameterContainer(clazz.typeParameters)) .setDeclarationContainer(serializeIrDeclarationContainer(clazz.declarations)) clazz.superTypes.forEach { diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrClass.java b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrClass.java index 77be52d4303..9c614d2a7a0 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrClass.java +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrClass.java @@ -198,6 +198,11 @@ public final class IrClass extends isExpect_ = input.readBool(); break; } + case 128: { + bitField0_ |= 0x00004000; + isFun_ = input.readBool(); + break; + } } } } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { @@ -475,6 +480,21 @@ public final class IrClass extends return isExpect_; } + public static final int IS_FUN_FIELD_NUMBER = 16; + private boolean isFun_; + /** + * required bool is_fun = 16; + */ + public boolean hasIsFun() { + return ((bitField0_ & 0x00004000) == 0x00004000); + } + /** + * required bool is_fun = 16; + */ + public boolean getIsFun() { + return isFun_; + } + private void initFields() { base_ = org.jetbrains.kotlin.backend.common.serialization.proto.IrDeclarationBase.getDefaultInstance(); name_ = 0; @@ -491,6 +511,7 @@ public final class IrClass extends declarationContainer_ = org.jetbrains.kotlin.backend.common.serialization.proto.IrDeclarationContainer.getDefaultInstance(); superType_ = java.util.Collections.emptyList(); isExpect_ = false; + isFun_ = false; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -550,6 +571,10 @@ public final class IrClass extends memoizedIsInitialized = 0; return false; } + if (!hasIsFun()) { + memoizedIsInitialized = 0; + return false; + } if (!getBase().isInitialized()) { memoizedIsInitialized = 0; return false; @@ -624,6 +649,9 @@ public final class IrClass extends if (((bitField0_ & 0x00002000) == 0x00002000)) { output.writeBool(15, isExpect_); } + if (((bitField0_ & 0x00004000) == 0x00004000)) { + output.writeBool(16, isFun_); + } output.writeRawBytes(unknownFields); } @@ -698,6 +726,10 @@ public final class IrClass extends size += org.jetbrains.kotlin.protobuf.CodedOutputStream .computeBoolSize(15, isExpect_); } + if (((bitField0_ & 0x00004000) == 0x00004000)) { + size += org.jetbrains.kotlin.protobuf.CodedOutputStream + .computeBoolSize(16, isFun_); + } size += unknownFields.size(); memoizedSerializedSize = size; return size; @@ -822,6 +854,8 @@ public final class IrClass extends bitField0_ = (bitField0_ & ~0x00002000); isExpect_ = false; bitField0_ = (bitField0_ & ~0x00004000); + isFun_ = false; + bitField0_ = (bitField0_ & ~0x00008000); return this; } @@ -906,6 +940,10 @@ public final class IrClass extends to_bitField0_ |= 0x00002000; } result.isExpect_ = isExpect_; + if (((from_bitField0_ & 0x00008000) == 0x00008000)) { + to_bitField0_ |= 0x00004000; + } + result.isFun_ = isFun_; result.bitField0_ = to_bitField0_; return result; } @@ -964,6 +1002,9 @@ public final class IrClass extends if (other.hasIsExpect()) { setIsExpect(other.getIsExpect()); } + if (other.hasIsFun()) { + setIsFun(other.getIsFun()); + } setUnknownFields( getUnknownFields().concat(other.unknownFields)); return this; @@ -1022,6 +1063,10 @@ public final class IrClass extends return false; } + if (!hasIsFun()) { + + return false; + } if (!getBase().isInitialized()) { return false; @@ -1742,6 +1787,38 @@ public final class IrClass extends return this; } + private boolean isFun_ ; + /** + * required bool is_fun = 16; + */ + public boolean hasIsFun() { + return ((bitField0_ & 0x00008000) == 0x00008000); + } + /** + * required bool is_fun = 16; + */ + public boolean getIsFun() { + return isFun_; + } + /** + * required bool is_fun = 16; + */ + public Builder setIsFun(boolean value) { + bitField0_ |= 0x00008000; + isFun_ = value; + + return this; + } + /** + * required bool is_fun = 16; + */ + public Builder clearIsFun() { + bitField0_ = (bitField0_ & ~0x00008000); + isFun_ = false; + + return this; + } + // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.backend.common.serialization.proto.IrClass) } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrClassOrBuilder.java b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrClassOrBuilder.java index 3b8911e6f27..8eb261aaaa0 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrClassOrBuilder.java +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrClassOrBuilder.java @@ -153,4 +153,13 @@ public interface IrClassOrBuilder extends * required bool is_expect = 15; */ boolean getIsExpect(); + + /** + * required bool is_fun = 16; + */ + boolean hasIsFun(); + /** + * required bool is_fun = 16; + */ + boolean getIsFun(); } \ No newline at end of file diff --git a/compiler/testData/codegen/box/funInterface/basicFunInterfaceConversion.kt b/compiler/testData/codegen/box/funInterface/basicFunInterfaceConversion.kt index 0d2cf38e9bc..d114edbee1c 100644 --- a/compiler/testData/codegen/box/funInterface/basicFunInterfaceConversion.kt +++ b/compiler/testData/codegen/box/funInterface/basicFunInterfaceConversion.kt @@ -1,7 +1,6 @@ // !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions // TARGET_BACKEND: JVM // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR fun interface Foo { fun invoke(): String diff --git a/compiler/testData/codegen/box/funInterface/castFromAny.kt b/compiler/testData/codegen/box/funInterface/castFromAny.kt index f53fca36ca6..51a293c66dc 100644 --- a/compiler/testData/codegen/box/funInterface/castFromAny.kt +++ b/compiler/testData/codegen/box/funInterface/castFromAny.kt @@ -1,7 +1,7 @@ // !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions // TARGET_BACKEND: JVM // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR + fun interface KRunnable { fun invoke() diff --git a/compiler/testData/codegen/box/funInterface/inlinedSamWrapper.kt b/compiler/testData/codegen/box/funInterface/inlinedSamWrapper.kt index f0ef007992f..812c9c45e48 100644 --- a/compiler/testData/codegen/box/funInterface/inlinedSamWrapper.kt +++ b/compiler/testData/codegen/box/funInterface/inlinedSamWrapper.kt @@ -1,7 +1,6 @@ // !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions // TARGET_BACKEND: JVM // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // WITH_RUNTIME fun interface MyRunnable { diff --git a/compiler/testData/codegen/box/funInterface/nullableSam.kt b/compiler/testData/codegen/box/funInterface/nullableSam.kt index 328994b7298..fe4b6581032 100644 --- a/compiler/testData/codegen/box/funInterface/nullableSam.kt +++ b/compiler/testData/codegen/box/funInterface/nullableSam.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/funInterface/partialSam.kt b/compiler/testData/codegen/box/funInterface/partialSam.kt index f7e411f2f26..058d058bf5d 100644 --- a/compiler/testData/codegen/box/funInterface/partialSam.kt +++ b/compiler/testData/codegen/box/funInterface/partialSam.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt b/compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt index 33301006563..7353f2755e9 100644 --- a/compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt +++ b/compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt b/compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt index 7674a2ef4f9..b75e31cbd95 100644 --- a/compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt +++ b/compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR // WITH_COROUTINES // WITH_RUNTIME diff --git a/compiler/testData/ir/irText/expressions/funInterface/basicFunInterfaceConversion.fir.txt b/compiler/testData/ir/irText/expressions/funInterface/basicFunInterfaceConversion.fir.txt new file mode 100644 index 00000000000..c31b6c40da7 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/funInterface/basicFunInterfaceConversion.fir.txt @@ -0,0 +1,32 @@ +FILE fqName: fileName:/basicFunInterfaceConversion.kt + CLASS INTERFACE name:Foo modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Foo + FUN name:invoke visibility:public modality:ABSTRACT <> ($this:.Foo) returnType:kotlin.String + $this: VALUE_PARAMETER name: type:.Foo + 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 [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: 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: 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: type:kotlin.Any + FUN name:foo visibility:public modality:FINAL <> (f:.Foo) returnType:kotlin.String + VALUE_PARAMETER name:f index:0 type:.Foo + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun foo (f: .Foo): kotlin.String declared in ' + CALL 'public abstract fun invoke (): kotlin.String declared in .Foo' type=kotlin.String origin=null + $this: GET_VAR 'f: .Foo declared in .foo' type=.Foo origin=null + FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test (): kotlin.String declared in ' + CALL 'public final fun foo (f: .Foo): kotlin.String declared in ' type=kotlin.String origin=null + f: FUN_EXPR type=kotlin.Function0 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + CONST String type=kotlin.String value="OK" diff --git a/compiler/testData/ir/irText/expressions/funInterface/basicFunInterfaceConversion.kt b/compiler/testData/ir/irText/expressions/funInterface/basicFunInterfaceConversion.kt new file mode 100644 index 00000000000..94f6bbcebbd --- /dev/null +++ b/compiler/testData/ir/irText/expressions/funInterface/basicFunInterfaceConversion.kt @@ -0,0 +1,9 @@ +// !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions + +fun interface Foo { + fun invoke(): String +} + +fun foo(f: Foo) = f.invoke() + +fun test() = foo { "OK" } \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/funInterface/basicFunInterfaceConversion.txt b/compiler/testData/ir/irText/expressions/funInterface/basicFunInterfaceConversion.txt new file mode 100644 index 00000000000..c50d837d025 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/funInterface/basicFunInterfaceConversion.txt @@ -0,0 +1,34 @@ +FILE fqName: fileName:/basicFunInterfaceConversion.kt + CLASS INTERFACE name:Foo modality:ABSTRACT visibility:public [fun] superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Foo + FUN name:invoke visibility:public modality:ABSTRACT <> ($this:.Foo) returnType:kotlin.String + $this: VALUE_PARAMETER name: type:.Foo + 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 [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: 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: 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: type:kotlin.Any + FUN name:foo visibility:public modality:FINAL <> (f:.Foo) returnType:kotlin.String + VALUE_PARAMETER name:f index:0 type:.Foo + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun foo (f: .Foo): kotlin.String declared in ' + CALL 'public abstract fun invoke (): kotlin.String declared in .Foo' type=kotlin.String origin=null + $this: GET_VAR 'f: .Foo declared in .foo' type=.Foo origin=null + FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test (): kotlin.String declared in ' + CALL 'public final fun foo (f: .Foo): kotlin.String declared in ' type=kotlin.String origin=null + f: TYPE_OP type=.Foo origin=SAM_CONVERSION typeOperand=.Foo + FUN_EXPR type=kotlin.Function0 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (): kotlin.String declared in .test' + CONST String type=kotlin.String value="OK" diff --git a/compiler/testData/ir/irText/expressions/funInterface/castFromAny.fir.txt b/compiler/testData/ir/irText/expressions/funInterface/castFromAny.fir.txt new file mode 100644 index 00000000000..cc65bb04717 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/funInterface/castFromAny.fir.txt @@ -0,0 +1,26 @@ +FILE fqName: fileName:/castFromAny.kt + CLASS INTERFACE name:KRunnable modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.KRunnable + FUN name:invoke visibility:public modality:ABSTRACT <> ($this:.KRunnable) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.KRunnable + 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 [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: 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: 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: type:kotlin.Any + FUN name:test visibility:public modality:FINAL <> (a:kotlin.Any?) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any? + BLOCK_BODY + TYPE_OP type=kotlin.Function0 origin=CAST typeOperand=kotlin.Function0 + GET_VAR 'a: kotlin.Any? declared in .test' type=kotlin.Any? origin=null + CALL 'public abstract fun invoke (): kotlin.Unit declared in .KRunnable' type=kotlin.Unit origin=null + $this: CALL 'public final fun KRunnable (block: kotlin.Function0): .KRunnable declared in ' type=.KRunnable origin=null + block: GET_VAR 'a: kotlin.Any? declared in .test' type=kotlin.Function0 origin=null diff --git a/compiler/testData/ir/irText/expressions/funInterface/castFromAny.kt b/compiler/testData/ir/irText/expressions/funInterface/castFromAny.kt new file mode 100644 index 00000000000..9581e8ee90f --- /dev/null +++ b/compiler/testData/ir/irText/expressions/funInterface/castFromAny.kt @@ -0,0 +1,11 @@ +// !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions + +fun interface KRunnable { + fun invoke() +} + +fun test(a: Any?) { + a as () -> Unit + KRunnable(a).invoke() +} + diff --git a/compiler/testData/ir/irText/expressions/funInterface/castFromAny.txt b/compiler/testData/ir/irText/expressions/funInterface/castFromAny.txt new file mode 100644 index 00000000000..1c13506c9b6 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/funInterface/castFromAny.txt @@ -0,0 +1,28 @@ +FILE fqName: fileName:/castFromAny.kt + CLASS INTERFACE name:KRunnable modality:ABSTRACT visibility:public [fun] superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.KRunnable + FUN name:invoke visibility:public modality:ABSTRACT <> ($this:.KRunnable) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.KRunnable + 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 [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: 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: 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: type:kotlin.Any + FUN name:test visibility:public modality:FINAL <> (a:kotlin.Any?) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any? + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + TYPE_OP type=kotlin.Function0 origin=CAST typeOperand=kotlin.Function0 + GET_VAR 'a: kotlin.Any? declared in .test' type=kotlin.Any? origin=null + CALL 'public abstract fun invoke (): kotlin.Unit declared in .KRunnable' type=kotlin.Unit origin=null + $this: TYPE_OP type=.KRunnable origin=SAM_CONVERSION typeOperand=.KRunnable + TYPE_OP type=kotlin.Function0 origin=IMPLICIT_CAST typeOperand=kotlin.Function0 + GET_VAR 'a: kotlin.Any? declared in .test' type=kotlin.Any? origin=null diff --git a/compiler/testData/ir/irText/expressions/funInterface/partialSam.fir.txt b/compiler/testData/ir/irText/expressions/funInterface/partialSam.fir.txt new file mode 100644 index 00000000000..722e3808df3 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/funInterface/partialSam.fir.txt @@ -0,0 +1,128 @@ +FILE fqName: fileName:/partialSam.kt + CLASS INTERFACE name:Fn modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Fn + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + TYPE_PARAMETER name:R index:1 variance: superTypes:[kotlin.Any?] + FUN name:run visibility:public modality:ABSTRACT <> ($this:.Fn, s:kotlin.String, i:kotlin.Int, t:T of .Fn) returnType:R of .Fn + $this: VALUE_PARAMETER name: type:.Fn + VALUE_PARAMETER name:s index:0 type:kotlin.String + VALUE_PARAMETER name:i index:1 type:kotlin.Int + VALUE_PARAMETER name:t index:2 type:T of .Fn + 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 [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: 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: 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: type:kotlin.Any + CLASS CLASS name:J modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.J + CONSTRUCTOR visibility:public <> () returnType:.J [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:J modality:FINAL visibility:public superTypes:[kotlin.Any]' + FUN name:runConversion visibility:public modality:FINAL <> ($this:.J, f1:.Fn, f2:.Fn) returnType:kotlin.Int + $this: VALUE_PARAMETER name: type:.J + VALUE_PARAMETER name:f1 index:0 type:.Fn + VALUE_PARAMETER name:f2 index:1 type:.Fn + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun runConversion (f1: .Fn, f2: .Fn): kotlin.Int declared in .J' + CALL 'public abstract fun run (s: kotlin.String, i: kotlin.Int, t: kotlin.String): kotlin.Int declared in .Fn' type=kotlin.Int origin=null + $this: GET_VAR 'f1: .Fn declared in .J.runConversion' type=.Fn origin=null + s: CONST String type=kotlin.String value="Bar" + i: CONST Int type=kotlin.Int value=1 + t: CALL 'public abstract fun run (s: kotlin.String, i: kotlin.Int, t: kotlin.Int): kotlin.String declared in .Fn' type=kotlin.String origin=null + $this: GET_VAR 'f2: .Fn declared in .J.runConversion' type=.Fn origin=null + s: CONST String type=kotlin.String value="Foo" + i: CONST Int type=kotlin.Int value=42 + t: CONST Int type=kotlin.Int value=239 + 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 [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: 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: 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: type:kotlin.Any + PROPERTY name:fsi visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:fsi type:. visibility:private [final,static] + EXPRESSION_BODY + BLOCK type=.fsi. origin=OBJECT_LITERAL + CLASS OBJECT name: modality:FINAL visibility:local superTypes:[.Fn] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.fsi. + CONSTRUCTOR visibility:private <> () returnType:kotlin.Any [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS OBJECT name: modality:FINAL visibility:local superTypes:[.Fn]' + FUN name:run visibility:public modality:FINAL <> ($this:.fsi., s:kotlin.String, i:kotlin.Int, t:kotlin.String) returnType:kotlin.Int + $this: VALUE_PARAMETER name: type:.fsi. + VALUE_PARAMETER name:s index:0 type:kotlin.String + VALUE_PARAMETER name:i index:1 type:kotlin.Int + VALUE_PARAMETER name:t index:2 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun run (s: kotlin.String, i: kotlin.Int, t: kotlin.String): kotlin.Int declared in .fsi.' + CONST Int type=kotlin.Int value=1 + CONSTRUCTOR_CALL 'private constructor () [primary] declared in .fsi.' type=.fsi. origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:. + correspondingProperty: PROPERTY name:fsi visibility:public modality:FINAL [val] + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): . declared in ' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:fsi type:. visibility:private [final,static]' type=. origin=null + PROPERTY name:fis visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:fis type:. visibility:private [final,static] + EXPRESSION_BODY + BLOCK type=.fis. origin=OBJECT_LITERAL + CLASS OBJECT name: modality:FINAL visibility:local superTypes:[.Fn] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.fis. + CONSTRUCTOR visibility:private <> () returnType:kotlin.Any [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS OBJECT name: modality:FINAL visibility:local superTypes:[.Fn]' + FUN name:run visibility:public modality:FINAL <> ($this:.fis., s:kotlin.String, i:kotlin.Int, t:kotlin.Int) returnType:kotlin.String + $this: VALUE_PARAMETER name: type:.fis. + VALUE_PARAMETER name:s index:0 type:kotlin.String + VALUE_PARAMETER name:i index:1 type:kotlin.Int + VALUE_PARAMETER name:t index:2 type:kotlin.Int + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun run (s: kotlin.String, i: kotlin.Int, t: kotlin.Int): kotlin.String declared in .fis.' + CONST String type=kotlin.String value="" + CONSTRUCTOR_CALL 'private constructor () [primary] declared in .fis.' type=.fis. origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:. + correspondingProperty: PROPERTY name:fis visibility:public modality:FINAL [val] + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): . declared in ' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:fis type:. visibility:private [final,static]' type=. origin=null + FUN name:test visibility:public modality:FINAL <> (j:.J) returnType:kotlin.Unit + VALUE_PARAMETER name:j index:0 type:.J + BLOCK_BODY + CALL 'public final fun runConversion (f1: .Fn, f2: .Fn): kotlin.Int declared in .J' type=kotlin.Int origin=null + $this: GET_VAR 'j: .J declared in .test' type=.J origin=null + f1: CALL 'public final fun (): . declared in ' type=. origin=null + f2: FUN_EXPR type=kotlin.Function3 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (s:kotlin.String, i:kotlin.Int, ti:kotlin.Int) returnType:kotlin.String + VALUE_PARAMETER name:s index:0 type:kotlin.String + VALUE_PARAMETER name:i index:1 type:kotlin.Int + VALUE_PARAMETER name:ti index:2 type:kotlin.Int + BLOCK_BODY + CONST String type=kotlin.String value="" + CALL 'public final fun runConversion (f1: .Fn, f2: .Fn): kotlin.Int declared in .J' type=kotlin.Int origin=null + $this: GET_VAR 'j: .J declared in .test' type=.J origin=null + f1: FUN_EXPR type=kotlin.Function3 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (s:kotlin.String, i:kotlin.Int, ts:kotlin.String) returnType:kotlin.Int + VALUE_PARAMETER name:s index:0 type:kotlin.String + VALUE_PARAMETER name:i index:1 type:kotlin.Int + VALUE_PARAMETER name:ts index:2 type:kotlin.String + BLOCK_BODY + CONST Int type=kotlin.Int value=1 + f2: CALL 'public final fun (): . declared in ' type=. origin=null diff --git a/compiler/testData/ir/irText/expressions/funInterface/partialSam.kt b/compiler/testData/ir/irText/expressions/funInterface/partialSam.kt new file mode 100644 index 00000000000..9050b87fc45 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/funInterface/partialSam.kt @@ -0,0 +1,28 @@ +// !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions +// TARGET_BACKEND: JVM +// IGNORE_BACKEND: JVM_IR +// IGNORE_BACKEND_FIR: JVM_IR +// WITH_RUNTIME + +fun interface Fn { + fun run(s: String, i: Int, t: T): R +} + +class J { + fun runConversion(f1: Fn, f2: Fn): Int { + return f1.run("Bar", 1, f2.run("Foo", 42, 239)) + } +} + +val fsi = object : Fn { + override fun run(s: String, i: Int, t: String): Int = 1 +} + +val fis = object : Fn { + override fun run(s: String, i: Int, t: Int): String = "" +} + +fun test(j: J) { + j.runConversion(fsi) { s, i, ti -> ""} + j.runConversion({ s, i, ts -> 1 }, fis) +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/funInterface/partialSam.txt b/compiler/testData/ir/irText/expressions/funInterface/partialSam.txt new file mode 100644 index 00000000000..7772abe4a0a --- /dev/null +++ b/compiler/testData/ir/irText/expressions/funInterface/partialSam.txt @@ -0,0 +1,164 @@ +FILE fqName: fileName:/partialSam.kt + CLASS INTERFACE name:Fn modality:ABSTRACT visibility:public [fun] superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Fn.Fn, R of .Fn> + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + TYPE_PARAMETER name:R index:1 variance: superTypes:[kotlin.Any?] + FUN name:run visibility:public modality:ABSTRACT <> ($this:.Fn.Fn, R of .Fn>, s:kotlin.String, i:kotlin.Int, t:T of .Fn) returnType:R of .Fn + $this: VALUE_PARAMETER name: type:.Fn.Fn, R of .Fn> + VALUE_PARAMETER name:s index:0 type:kotlin.String + VALUE_PARAMETER name:i index:1 type:kotlin.Int + VALUE_PARAMETER name:t index:2 type:T of .Fn + 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 [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: 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: 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: type:kotlin.Any + CLASS CLASS name:J modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.J + CONSTRUCTOR visibility:public <> () returnType:.J [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:J modality:FINAL visibility:public superTypes:[kotlin.Any]' + FUN name:runConversion visibility:public modality:FINAL <> ($this:.J, f1:.Fn, f2:.Fn) returnType:kotlin.Int + $this: VALUE_PARAMETER name: type:.J + VALUE_PARAMETER name:f1 index:0 type:.Fn + VALUE_PARAMETER name:f2 index:1 type:.Fn + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun runConversion (f1: .Fn, f2: .Fn): kotlin.Int declared in .J' + CALL 'public abstract fun run (s: kotlin.String, i: kotlin.Int, t: T of .Fn): R of .Fn declared in .Fn' type=kotlin.Int origin=null + $this: GET_VAR 'f1: .Fn declared in .J.runConversion' type=.Fn origin=null + s: CONST String type=kotlin.String value="Bar" + i: CONST Int type=kotlin.Int value=1 + t: CALL 'public abstract fun run (s: kotlin.String, i: kotlin.Int, t: T of .Fn): R of .Fn declared in .Fn' type=kotlin.String origin=null + $this: GET_VAR 'f2: .Fn declared in .J.runConversion' type=.Fn origin=null + s: CONST String type=kotlin.String value="Foo" + i: CONST Int type=kotlin.Int value=42 + t: CONST Int type=kotlin.Int value=239 + 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 [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: 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: 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: type:kotlin.Any + PROPERTY name:fsi visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:fsi type:.Fn visibility:private [final,static] + EXPRESSION_BODY + BLOCK type=.fsi. origin=OBJECT_LITERAL + CLASS CLASS name: modality:FINAL visibility:local superTypes:[.Fn] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.fsi. + CONSTRUCTOR visibility:public <> () returnType:.fsi. [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name: modality:FINAL visibility:local superTypes:[.Fn]' + FUN name:run visibility:public modality:OPEN <> ($this:.fsi., s:kotlin.String, i:kotlin.Int, t:kotlin.String) returnType:kotlin.Int + overridden: + public abstract fun run (s: kotlin.String, i: kotlin.Int, t: T of .Fn): R of .Fn declared in .Fn + $this: VALUE_PARAMETER name: type:.fsi. + VALUE_PARAMETER name:s index:0 type:kotlin.String + VALUE_PARAMETER name:i index:1 type:kotlin.Int + VALUE_PARAMETER name:t index:2 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun run (s: kotlin.String, i: kotlin.Int, t: kotlin.String): kotlin.Int declared in .fsi.' + CONST Int type=kotlin.Int value=1 + 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 [fake_override,operator] declared in .Fn + $this: VALUE_PARAMETER name: 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 [fake_override] declared in .Fn + $this: VALUE_PARAMETER name: 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 [fake_override] declared in .Fn + $this: VALUE_PARAMETER name: type:kotlin.Any + CONSTRUCTOR_CALL 'public constructor () [primary] declared in .fsi.' type=.fsi. origin=OBJECT_LITERAL + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:.Fn + correspondingProperty: PROPERTY name:fsi visibility:public modality:FINAL [val] + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): .Fn declared in ' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:fsi type:.Fn visibility:private [final,static]' type=.Fn origin=null + PROPERTY name:fis visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:fis type:.Fn visibility:private [final,static] + EXPRESSION_BODY + BLOCK type=.fis. origin=OBJECT_LITERAL + CLASS CLASS name: modality:FINAL visibility:local superTypes:[.Fn] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.fis. + CONSTRUCTOR visibility:public <> () returnType:.fis. [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name: modality:FINAL visibility:local superTypes:[.Fn]' + FUN name:run visibility:public modality:OPEN <> ($this:.fis., s:kotlin.String, i:kotlin.Int, t:kotlin.Int) returnType:kotlin.String + overridden: + public abstract fun run (s: kotlin.String, i: kotlin.Int, t: T of .Fn): R of .Fn declared in .Fn + $this: VALUE_PARAMETER name: type:.fis. + VALUE_PARAMETER name:s index:0 type:kotlin.String + VALUE_PARAMETER name:i index:1 type:kotlin.Int + VALUE_PARAMETER name:t index:2 type:kotlin.Int + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun run (s: kotlin.String, i: kotlin.Int, t: kotlin.Int): kotlin.String declared in .fis.' + CONST String type=kotlin.String value="" + 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 [fake_override,operator] declared in .Fn + $this: VALUE_PARAMETER name: 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 [fake_override] declared in .Fn + $this: VALUE_PARAMETER name: 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 [fake_override] declared in .Fn + $this: VALUE_PARAMETER name: type:kotlin.Any + CONSTRUCTOR_CALL 'public constructor () [primary] declared in .fis.' type=.fis. origin=OBJECT_LITERAL + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:.Fn + correspondingProperty: PROPERTY name:fis visibility:public modality:FINAL [val] + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): .Fn declared in ' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:fis type:.Fn visibility:private [final,static]' type=.Fn origin=null + FUN name:test visibility:public modality:FINAL <> (j:.J) returnType:kotlin.Unit + VALUE_PARAMETER name:j index:0 type:.J + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + CALL 'public final fun runConversion (f1: .Fn, f2: .Fn): kotlin.Int declared in .J' type=kotlin.Int origin=null + $this: GET_VAR 'j: .J declared in .test' type=.J origin=null + f1: CALL 'public final fun (): .Fn declared in ' type=.Fn origin=GET_PROPERTY + f2: TYPE_OP type=.Fn origin=SAM_CONVERSION typeOperand=.Fn + FUN_EXPR type=kotlin.Function3<@[ParameterName(name = 's')] kotlin.String, @[ParameterName(name = 'i')] kotlin.Int, @[ParameterName(name = 't')] kotlin.Int, kotlin.String> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (s:kotlin.String, i:kotlin.Int, ti:kotlin.Int) returnType:kotlin.String + VALUE_PARAMETER name:s index:0 type:kotlin.String + VALUE_PARAMETER name:i index:1 type:kotlin.Int + VALUE_PARAMETER name:ti index:2 type:kotlin.Int + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (s: kotlin.String, i: kotlin.Int, ti: kotlin.Int): kotlin.String declared in .test' + CONST String type=kotlin.String value="" + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + CALL 'public final fun runConversion (f1: .Fn, f2: .Fn): kotlin.Int declared in .J' type=kotlin.Int origin=null + $this: GET_VAR 'j: .J declared in .test' type=.J origin=null + f1: TYPE_OP type=.Fn origin=SAM_CONVERSION typeOperand=.Fn + FUN_EXPR type=kotlin.Function3<@[ParameterName(name = 's')] kotlin.String, @[ParameterName(name = 'i')] kotlin.Int, @[ParameterName(name = 't')] kotlin.String, kotlin.Int> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (s:kotlin.String, i:kotlin.Int, ts:kotlin.String) returnType:kotlin.Int + VALUE_PARAMETER name:s index:0 type:kotlin.String + VALUE_PARAMETER name:i index:1 type:kotlin.Int + VALUE_PARAMETER name:ts index:2 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (s: kotlin.String, i: kotlin.Int, ts: kotlin.String): kotlin.Int declared in .test' + CONST Int type=kotlin.Int value=1 + f2: CALL 'public final fun (): .Fn declared in ' type=.Fn origin=GET_PROPERTY diff --git a/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.fir.txt b/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.fir.txt new file mode 100644 index 00000000000..6febaf26279 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.fir.txt @@ -0,0 +1,113 @@ +FILE fqName: fileName:/samConversionsWithSmartCasts.kt + CLASS INTERFACE name:KRunnable modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.KRunnable + FUN name:run visibility:public modality:ABSTRACT <> ($this:.KRunnable) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.KRunnable + 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 [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: 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: 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: type:kotlin.Any + FUN name:id visibility:public modality:FINAL (x:T of .id) returnType:T of .id + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + VALUE_PARAMETER name:x index:0 type:T of .id + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun id (x: T of .id): T of .id declared in ' + GET_VAR 'x: T of .id declared in .id' type=T of .id origin=null + FUN name:run1 visibility:public modality:FINAL <> (r:.KRunnable) returnType:kotlin.Unit + VALUE_PARAMETER name:r index:0 type:.KRunnable + BLOCK_BODY + FUN name:run2 visibility:public modality:FINAL <> (r1:.KRunnable, r2:.KRunnable) returnType:kotlin.Unit + VALUE_PARAMETER name:r1 index:0 type:.KRunnable + VALUE_PARAMETER name:r2 index:1 type:.KRunnable + BLOCK_BODY + FUN name:test0 visibility:public modality:FINAL (a:T of .test0) returnType:kotlin.Unit + TYPE_PARAMETER name:T index:0 variance: superTypes:[.KRunnable; kotlin.Function0] + VALUE_PARAMETER name:a index:0 type:T of .test0 + BLOCK_BODY + CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: GET_VAR 'a: T of .test0 declared in .test0' type=T of .test0 origin=null + FUN name:test1 visibility:public modality:FINAL <> (a:kotlin.Function0) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Function0 + BLOCK_BODY + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.KRunnable + GET_VAR 'a: kotlin.Function0 declared in .test1' type=kotlin.Function0 origin=null + then: CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: GET_VAR 'a: kotlin.Function0 declared in .test1' type=.KRunnable origin=null + FUN name:test2 visibility:public modality:FINAL <> (a:.KRunnable) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:.KRunnable + BLOCK_BODY + TYPE_OP type=kotlin.Function0 origin=CAST typeOperand=kotlin.Function0 + GET_VAR 'a: .KRunnable declared in .test2' type=.KRunnable origin=null + CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: GET_VAR 'a: .KRunnable declared in .test2' type=kotlin.Function0 origin=null + FUN name:test3 visibility:public modality:FINAL <> (a:kotlin.Function0) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Function0 + BLOCK_BODY + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.KRunnable + GET_VAR 'a: kotlin.Function0 declared in .test3' type=kotlin.Function0 origin=null + then: CALL 'public final fun run2 (r1: .KRunnable, r2: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r1: GET_VAR 'a: kotlin.Function0 declared in .test3' type=.KRunnable origin=null + r2: GET_VAR 'a: kotlin.Function0 declared in .test3' type=.KRunnable origin=null + FUN name:test4 visibility:public modality:FINAL <> (a:kotlin.Function0, b:kotlin.Function0) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Function0 + VALUE_PARAMETER name:b index:1 type:kotlin.Function0 + BLOCK_BODY + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.KRunnable + GET_VAR 'a: kotlin.Function0 declared in .test4' type=kotlin.Function0 origin=null + then: CALL 'public final fun run2 (r1: .KRunnable, r2: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r1: GET_VAR 'a: kotlin.Function0 declared in .test4' type=.KRunnable origin=null + r2: GET_VAR 'b: kotlin.Function0 declared in .test4' type=kotlin.Function0 origin=null + FUN name:test5 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.KRunnable + GET_VAR 'a: kotlin.Any declared in .test5' type=kotlin.Any origin=null + then: CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: GET_VAR 'a: kotlin.Any declared in .test5' type=.KRunnable origin=null + FUN name:test5x visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.KRunnable + GET_VAR 'a: kotlin.Any declared in .test5x' type=kotlin.Any origin=null + then: BLOCK type=kotlin.Unit origin=null + TYPE_OP type=kotlin.Function0 origin=CAST typeOperand=kotlin.Function0 + GET_VAR 'a: kotlin.Any declared in .test5x' type=.KRunnable origin=null + CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: GET_VAR 'a: kotlin.Any declared in .test5x' type=.KRunnable origin=null + FUN name:test6 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + TYPE_OP type=kotlin.Function0 origin=CAST typeOperand=kotlin.Function0 + GET_VAR 'a: kotlin.Any declared in .test6' type=kotlin.Any origin=null + CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: GET_VAR 'a: kotlin.Any declared in .test6' type=kotlin.Function0 origin=null + FUN name:test8 visibility:public modality:FINAL <> (a:kotlin.Function0) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Function0 + BLOCK_BODY + CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: CALL 'public final fun id (x: T of .id): T of .id declared in ' type=kotlin.Function0 origin=null + : kotlin.Function0 + x: GET_VAR 'a: kotlin.Function0 declared in .test8' type=kotlin.Function0 origin=null + FUN name:test9 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: FUNCTION_REFERENCE 'public final fun test9 (): kotlin.Unit declared in ' type=kotlin.reflect.KFunction0 origin=null diff --git a/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.kt b/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.kt new file mode 100644 index 00000000000..5a09bc36b7c --- /dev/null +++ b/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.kt @@ -0,0 +1,83 @@ +// !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions +fun interface KRunnable { + fun run() +} + +fun id(x: T) = x + +fun run1(r: KRunnable) {} +fun run2(r1: KRunnable, r2: KRunnable) {} + +fun test0(a: T) where T : KRunnable, T : () -> Unit { + run1(a) +} + +fun test1(a: () -> Unit) { + if (a is KRunnable) { + run1(a) + } +} + +fun test2(a: KRunnable) { + a as () -> Unit + run1(a) +} + +fun test3(a: () -> Unit) { + if (a is KRunnable) { + run2(a, a) + } +} + +fun test4(a: () -> Unit, b: () -> Unit) { + if (a is KRunnable) { + run2(a, b) + } +} + +fun test5(a: Any) { + if (a is KRunnable) { + run1(a) + } +} + +fun test5x(a: Any) { + if (a is KRunnable) { + a as () -> Unit + run1(a) + } +} + +fun test6(a: Any) { + a as () -> Unit + run1(a) +} + +// TODO see KT-36013 +//fun test7(a: (Int) -> Int) { +// a as () -> Unit +// run1(a) +//} +// +//fun Int> test7a(a: T) { +// a as () -> Unit +// run1(a) +//} +// +//fun test7b(a: T) where T : (Int) -> Int, T : () -> Unit { +// run1(a) +//} +// +//interface Unrelated +// +//fun test7c(a: T) where T : Unrelated, T : () -> Unit { +// run1(a) +//} + +fun test8(a: () -> Unit) { + run1(id(a)) +} + +fun test9() { + run1(::test9) +} diff --git a/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.txt b/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.txt new file mode 100644 index 00000000000..3a6b016ee1d --- /dev/null +++ b/compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.txt @@ -0,0 +1,131 @@ +FILE fqName: fileName:/samConversionsWithSmartCasts.kt + CLASS INTERFACE name:KRunnable modality:ABSTRACT visibility:public [fun] superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.KRunnable + FUN name:run visibility:public modality:ABSTRACT <> ($this:.KRunnable) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.KRunnable + 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 [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: 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: 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: type:kotlin.Any + FUN name:id visibility:public modality:FINAL (x:T of .id) returnType:T of .id + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + VALUE_PARAMETER name:x index:0 type:T of .id + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun id (x: T of .id): T of .id declared in ' + GET_VAR 'x: T of .id declared in .id' type=T of .id origin=null + FUN name:run1 visibility:public modality:FINAL <> (r:.KRunnable) returnType:kotlin.Unit + VALUE_PARAMETER name:r index:0 type:.KRunnable + BLOCK_BODY + FUN name:run2 visibility:public modality:FINAL <> (r1:.KRunnable, r2:.KRunnable) returnType:kotlin.Unit + VALUE_PARAMETER name:r1 index:0 type:.KRunnable + VALUE_PARAMETER name:r2 index:1 type:.KRunnable + BLOCK_BODY + FUN name:test0 visibility:public modality:FINAL (a:T of .test0) returnType:kotlin.Unit + TYPE_PARAMETER name:T index:0 variance: superTypes:[.KRunnable; kotlin.Function0] + VALUE_PARAMETER name:a index:0 type:T of .test0 + BLOCK_BODY + CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: GET_VAR 'a: T of .test0 declared in .test0' type=T of .test0 origin=null + FUN name:test1 visibility:public modality:FINAL <> (a:kotlin.Function0) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Function0 + BLOCK_BODY + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.KRunnable + GET_VAR 'a: kotlin.Function0 declared in .test1' type=kotlin.Function0 origin=null + then: BLOCK type=kotlin.Unit origin=null + CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable + GET_VAR 'a: kotlin.Function0 declared in .test1' type=kotlin.Function0 origin=null + FUN name:test2 visibility:public modality:FINAL <> (a:.KRunnable) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:.KRunnable + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + TYPE_OP type=kotlin.Function0 origin=CAST typeOperand=kotlin.Function0 + GET_VAR 'a: .KRunnable declared in .test2' type=.KRunnable origin=null + CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: GET_VAR 'a: .KRunnable declared in .test2' type=.KRunnable origin=null + FUN name:test3 visibility:public modality:FINAL <> (a:kotlin.Function0) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Function0 + BLOCK_BODY + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.KRunnable + GET_VAR 'a: kotlin.Function0 declared in .test3' type=kotlin.Function0 origin=null + then: BLOCK type=kotlin.Unit origin=null + CALL 'public final fun run2 (r1: .KRunnable, r2: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r1: TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable + GET_VAR 'a: kotlin.Function0 declared in .test3' type=kotlin.Function0 origin=null + r2: TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable + GET_VAR 'a: kotlin.Function0 declared in .test3' type=kotlin.Function0 origin=null + FUN name:test4 visibility:public modality:FINAL <> (a:kotlin.Function0, b:kotlin.Function0) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Function0 + VALUE_PARAMETER name:b index:1 type:kotlin.Function0 + BLOCK_BODY + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.KRunnable + GET_VAR 'a: kotlin.Function0 declared in .test4' type=kotlin.Function0 origin=null + then: BLOCK type=kotlin.Unit origin=null + CALL 'public final fun run2 (r1: .KRunnable, r2: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r1: TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable + GET_VAR 'a: kotlin.Function0 declared in .test4' type=kotlin.Function0 origin=null + r2: TYPE_OP type=.KRunnable origin=SAM_CONVERSION typeOperand=.KRunnable + GET_VAR 'b: kotlin.Function0 declared in .test4' type=kotlin.Function0 origin=null + FUN name:test5 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.KRunnable + GET_VAR 'a: kotlin.Any declared in .test5' type=kotlin.Any origin=null + then: BLOCK type=kotlin.Unit origin=null + CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable + GET_VAR 'a: kotlin.Any declared in .test5' type=kotlin.Any origin=null + FUN name:test5x visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.KRunnable + GET_VAR 'a: kotlin.Any declared in .test5x' type=kotlin.Any origin=null + then: BLOCK type=kotlin.Unit origin=null + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + TYPE_OP type=kotlin.Function0 origin=CAST typeOperand=kotlin.Function0 + GET_VAR 'a: kotlin.Any declared in .test5x' type=kotlin.Any origin=null + CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: TYPE_OP type=.KRunnable origin=IMPLICIT_CAST typeOperand=.KRunnable + GET_VAR 'a: kotlin.Any declared in .test5x' type=kotlin.Any origin=null + FUN name:test6 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + TYPE_OP type=kotlin.Function0 origin=CAST typeOperand=kotlin.Function0 + GET_VAR 'a: kotlin.Any declared in .test6' type=kotlin.Any origin=null + CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: TYPE_OP type=.KRunnable origin=SAM_CONVERSION typeOperand=.KRunnable + TYPE_OP type=kotlin.Function0 origin=IMPLICIT_CAST typeOperand=kotlin.Function0 + GET_VAR 'a: kotlin.Any declared in .test6' type=kotlin.Any origin=null + FUN name:test8 visibility:public modality:FINAL <> (a:kotlin.Function0) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Function0 + BLOCK_BODY + CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: TYPE_OP type=.KRunnable origin=SAM_CONVERSION typeOperand=.KRunnable + CALL 'public final fun id (x: T of .id): T of .id declared in ' type=kotlin.Function0 origin=null + : kotlin.Function0 + x: GET_VAR 'a: kotlin.Function0 declared in .test8' type=kotlin.Function0 origin=null + FUN name:test9 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun run1 (r: .KRunnable): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: TYPE_OP type=.KRunnable origin=SAM_CONVERSION typeOperand=.KRunnable + FUNCTION_REFERENCE 'public final fun test9 (): kotlin.Unit declared in ' type=kotlin.reflect.KFunction0 origin=null diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 21b62e692f4..df7dad6883e 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -1419,6 +1419,39 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { } } + @TestMetadata("compiler/testData/ir/irText/expressions/funInterface") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class FunInterface extends AbstractIrTextTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInFunInterface() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irText/expressions/funInterface"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("basicFunInterfaceConversion.kt") + public void testBasicFunInterfaceConversion() throws Exception { + runTest("compiler/testData/ir/irText/expressions/funInterface/basicFunInterfaceConversion.kt"); + } + + @TestMetadata("castFromAny.kt") + public void testCastFromAny() throws Exception { + runTest("compiler/testData/ir/irText/expressions/funInterface/castFromAny.kt"); + } + + @TestMetadata("partialSam.kt") + public void testPartialSam() throws Exception { + runTest("compiler/testData/ir/irText/expressions/funInterface/partialSam.kt"); + } + + @TestMetadata("samConversionsWithSmartCasts.kt") + public void testSamConversionsWithSmartCasts() throws Exception { + runTest("compiler/testData/ir/irText/expressions/funInterface/samConversionsWithSmartCasts.kt"); + } + } + @TestMetadata("compiler/testData/ir/irText/expressions/sam") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinAbiVersion.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinAbiVersion.kt index d97b96f41ca..cf77c0eaf00 100644 --- a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinAbiVersion.kt +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinAbiVersion.kt @@ -22,7 +22,7 @@ fun String.parseKonanAbiVersion(): KotlinAbiVersion { data class KotlinAbiVersion(val version: Int) { companion object { - val CURRENT = KotlinAbiVersion(23) + val CURRENT = KotlinAbiVersion(24) } override fun toString() = "$version"