From 584b70719e1129d37e27b5292a6981e5a3b497b4 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 22 Apr 2022 00:15:11 +0200 Subject: [PATCH] JVM IR: disable SAM conversion in case type has 'in' projection ... and the corresponding type parameter has a non-trivial (i.e. non-`Any?`) upper bound. The best solution here would be to get rid of `removeExternalProjections` completely, and just use the type of the argument at the call site, but see KT-52428. #KT-51868 Fixed --- .../kotlin/backend/common/SamTypeFactory.kt | 30 +++++++++--- .../binding/CodegenAnnotatingVisitor.java | 8 ++-- .../FirBlackBoxCodegenTestGenerated.java | 6 +++ .../backend/jvm/JvmGeneratorExtensionsImpl.kt | 16 +++---- .../generators/ArgumentsGenerationUtils.kt | 5 +- .../psi2ir/generators/GeneratorExtensions.kt | 2 + .../sam/kt51868_contravariantGenericSam.kt | 47 +++++++++++++++++++ .../genericWithInProjection.kt | 7 ++- .../ir/irText/firProblems/kt19251.ir.txt | 15 +++--- .../ir/irText/firProblems/kt19251.kt.txt | 2 +- .../types/intersectionTypeInSamType.ir.txt | 34 +++++++------- .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++ .../LightAnalysisModeTestGenerated.java | 5 ++ 14 files changed, 138 insertions(+), 51 deletions(-) create mode 100644 compiler/testData/codegen/box/invokedynamic/sam/kt51868_contravariantGenericSam.kt diff --git a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/SamTypeFactory.kt b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/SamTypeFactory.kt index a5e035968e3..a0b53c18758 100644 --- a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/SamTypeFactory.kt +++ b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/SamTypeFactory.kt @@ -10,13 +10,17 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.types.* -import org.jetbrains.kotlin.types.checker.intersectWrappedTypes +import org.jetbrains.kotlin.types.typeUtil.asTypeProjection +import org.jetbrains.kotlin.types.typeUtil.isNullableAny import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithNothing class SamTypeApproximator(builtIns: KotlinBuiltIns, languageVersionSettings: LanguageVersionSettings) { private val typeApproximator = TypeApproximator(builtIns, languageVersionSettings) - fun getSamTypeForValueParameter(valueParameter: ValueParameterDescriptor): KotlinType? { + fun getSamTypeForValueParameter( + valueParameter: ValueParameterDescriptor, + carefulApproximationOfContravariantProjection: Boolean, + ): KotlinType? { val singleArgumentType: KotlinType val originalSingleArgumentType: KotlinType? val varargElementType = valueParameter.varargElementType @@ -54,14 +58,26 @@ class SamTypeApproximator(builtIns: KotlinBuiltIns, languageVersionSettings: Lan ) ?: originalTypeToUse approximatedOriginalTypeToUse as KotlinType - return approximatedOriginalTypeToUse.removeExternalProjections() + return approximatedOriginalTypeToUse.removeExternalProjections(carefulApproximationOfContravariantProjection) } - private fun KotlinType.removeExternalProjections(): KotlinType { - val newArguments = arguments.map { TypeProjectionImpl(Variance.INVARIANT, it.type) } + private fun KotlinType.removeExternalProjections(carefulApproximationOfContravariantProjection: Boolean): KotlinType? { + val newArguments = arguments.mapIndexed { i, argument -> + if (carefulApproximationOfContravariantProjection && argument.projectionKind == Variance.IN_VARIANCE) { + // 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` and a method that takes e.g. `A`, we check + // if `T` has a non-trivial upper bound. If it has one, we don't attempt to perform a SAM conversion at all. + // Otherwise we erase the type to `Any?`, so `A` becomes `A`, which is the computed SAM type. + val parameter = constructor.parameters.getOrNull(i) ?: return null + val upperBound = parameter.upperBounds.singleOrNull()?.upperIfFlexible() ?: return null + if (!upperBound.isNullableAny()) return null + + upperBound.asTypeProjection() + } else TypeProjectionImpl(Variance.INVARIANT, argument.type) + } return replace(newArguments) } - } open class SamTypeFactory { @@ -73,4 +89,4 @@ open class SamTypeFactory { fun create(originalType: KotlinType): SamType? { return if (isSamType(originalType)) SamType(originalType) else null } -} \ No newline at end of file +} diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java index f1fd04e6cc1..6f7b0b761d9 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java @@ -15,6 +15,7 @@ import kotlin.Pair; import kotlin.collections.CollectionsKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.backend.common.SamType; import org.jetbrains.kotlin.backend.common.SamTypeApproximator; import org.jetbrains.kotlin.builtins.FunctionTypesKt; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; @@ -26,7 +27,6 @@ import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.when.SwitchCodegenProvider; import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping; import org.jetbrains.kotlin.config.JvmDefaultMode; -import org.jetbrains.kotlin.config.LanguageFeature; import org.jetbrains.kotlin.config.LanguageVersionSettings; import org.jetbrains.kotlin.coroutines.CoroutineUtilKt; import org.jetbrains.kotlin.descriptors.*; @@ -45,11 +45,11 @@ import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingTrace; import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils; -import org.jetbrains.kotlin.resolve.calls.util.CallUtilKt; import org.jetbrains.kotlin.resolve.calls.model.*; import org.jetbrains.kotlin.resolve.calls.tower.NewAbstractResolvedCall; import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl; import org.jetbrains.kotlin.resolve.calls.tower.NewVariableAsFunctionResolvedCallImpl; +import org.jetbrains.kotlin.resolve.calls.util.CallUtilKt; import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.kotlin.resolve.constants.EnumValue; import org.jetbrains.kotlin.resolve.constants.NullValue; @@ -59,14 +59,12 @@ import org.jetbrains.kotlin.resolve.sam.SamConstructorDescriptor; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver; import org.jetbrains.kotlin.types.KotlinType; -import org.jetbrains.kotlin.backend.common.SamType; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; import org.jetbrains.org.objectweb.asm.Type; import java.util.*; import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*; -import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.NUMBERED_FUNCTION_PREFIX; import static org.jetbrains.kotlin.lexer.KtTokens.*; import static org.jetbrains.kotlin.name.SpecialNames.safeIdentifier; import static org.jetbrains.kotlin.resolve.BindingContext.*; @@ -819,7 +817,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { @Nullable private SamType createSamTypeByValueParameter(ValueParameterDescriptor valueParameterDescriptor) { - KotlinType kotlinSamType = samTypeApproximator.getSamTypeForValueParameter(valueParameterDescriptor); + KotlinType kotlinSamType = samTypeApproximator.getSamTypeForValueParameter(valueParameterDescriptor, false); if (kotlinSamType == null) return null; if (!JavaSingleAbstractMethodUtils.isSamType(kotlinSamType)) return null; return new SamType(kotlinSamType); diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 673c645543d..393a0e4569b 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -26606,6 +26606,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/invokedynamic/sam/kt47510.kt"); } + @Test + @TestMetadata("kt51868_contravariantGenericSam.kt") + public void testKt51868_contravariantGenericSam() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/sam/kt51868_contravariantGenericSam.kt"); + } + @Test @TestMetadata("kt52040_severalProxyFunsInInit.kt") public void testKt52040_severalProxyFunsInInit() throws Exception { diff --git a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt index 8e5d7deb6bb..c19d7ec94e4 100644 --- a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt +++ b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt @@ -6,10 +6,7 @@ package org.jetbrains.kotlin.backend.jvm import org.jetbrains.kotlin.backend.common.serialization.signature.PublicIdSignatureComputer -import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.config.JVMConfigurationKeys -import org.jetbrains.kotlin.config.JvmSerializeIrMode -import org.jetbrains.kotlin.config.languageVersionSettings +import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.FilteredAnnotations import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -53,7 +50,7 @@ import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations import org.jetbrains.kotlin.utils.addToStdlib.safeAs open class JvmGeneratorExtensionsImpl( - configuration: CompilerConfiguration, + private val configuration: CompilerConfiguration, private val generateFacades: Boolean = true, ) : GeneratorExtensions(), JvmGeneratorExtensions { override val classNameOverride: MutableMap = mutableMapOf() @@ -62,15 +59,14 @@ open class JvmGeneratorExtensionsImpl( override val cachedFields = CachedFieldsForObjectInstances(IrFactoryImpl, configuration.languageVersionSettings) - override val samConversion: SamConversion - get() = JvmSamConversion - - open class JvmSamConversion : SamConversion() { + override val samConversion: SamConversion = JvmSamConversion() + inner class JvmSamConversion : SamConversion() { override fun isPlatformSamType(type: KotlinType): Boolean = JavaSingleAbstractMethodUtils.isSamType(type) - companion object Instance : JvmSamConversion() + override fun isCarefulApproximationOfContravariantProjection(): Boolean = + configuration.get(JVMConfigurationKeys.SAM_CONVERSIONS) != JvmClosureGenerationScheme.CLASS } override fun getContainerSource(descriptor: DeclarationDescriptor): DeserializedContainerSource? { diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt index 1a2d72dd14d..05f4a4373ae 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt @@ -737,8 +737,9 @@ fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: Ca } private fun StatementGenerator.getSamTypeForValueParameter(valueParameter: ValueParameterDescriptor): KotlinType? { - val approximatedSamType = context.samTypeApproximator.getSamTypeForValueParameter(valueParameter) - ?: return null + val approximatedSamType = context.samTypeApproximator.getSamTypeForValueParameter( + valueParameter, context.extensions.samConversion.isCarefulApproximationOfContravariantProjection(), + ) ?: return null if (!context.extensions.samConversion.isSamType(approximatedSamType)) return null val classDescriptor = approximatedSamType.constructor.declarationDescriptor diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt index 51a8af1dad9..ef971a2caa9 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt @@ -23,6 +23,8 @@ open class GeneratorExtensions : StubGeneratorExtensions() { open class SamConversion { open fun isPlatformSamType(type: KotlinType): Boolean = false + open fun isCarefulApproximationOfContravariantProjection(): Boolean = false + companion object Instance : SamConversion() } diff --git a/compiler/testData/codegen/box/invokedynamic/sam/kt51868_contravariantGenericSam.kt b/compiler/testData/codegen/box/invokedynamic/sam/kt51868_contravariantGenericSam.kt new file mode 100644 index 00000000000..ba4af8f028f --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/sam/kt51868_contravariantGenericSam.kt @@ -0,0 +1,47 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// FIR status: "ClassCastException: String cannot be cast to StringBuilder". +// FIR always takes the parameter type and erases type projections in it to obtain the SAM type. This is incorrect, see KT-51868 and KT-52428. + +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// WITH_STDLIB + +// CHECK_BYTECODE_TEXT +// JVM_IR_TEMPLATES +// 0 java/lang/invoke/LambdaMetafactory + +// FILE: box.kt + +fun box(): String { + var result = "Fail" + val r = Request { obj: CharSequence -> + result = obj as String + } + r.deliver("OK") + return result +} + +// FILE: Request.java + +public class Request { + private final Consumer consumer; + + public Request(Consumer consumer) { + this.consumer = consumer; + } + + public void deliver(Object response) { + deliverResponse(consumer, response); + } + + public void deliverResponse(final Consumer consumer, Object rawResponse) { + K response = (K) rawResponse; + consumer.accept(response); + } +} + +// FILE: Consumer.java + +public interface Consumer { + void accept(T t); +} diff --git a/compiler/testData/codegen/box/invokedynamic/sam/specializedGenerics/genericWithInProjection.kt b/compiler/testData/codegen/box/invokedynamic/sam/specializedGenerics/genericWithInProjection.kt index 3285a7475a5..556419a8406 100644 --- a/compiler/testData/codegen/box/invokedynamic/sam/specializedGenerics/genericWithInProjection.kt +++ b/compiler/testData/codegen/box/invokedynamic/sam/specializedGenerics/genericWithInProjection.kt @@ -1,10 +1,15 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// FIR status: the test passes but LambdaMetafactory is used, so bytecode text check fails. +// In this case FIR behavior is fine but it works because of a hack in + // TARGET_BACKEND: JVM // JVM_TARGET: 1.8 // SAM_CONVERSIONS: INDY // CHECK_BYTECODE_TEXT // JVM_IR_TEMPLATES -// 1 java/lang/invoke/LambdaMetafactory +// 0 java/lang/invoke/LambdaMetafactory +// TODO: restore indy for SAM types with contravariant projections. See KT-52428 for more info. fun interface Cmp { fun compare(a: T, b: T): Int diff --git a/compiler/testData/ir/irText/firProblems/kt19251.ir.txt b/compiler/testData/ir/irText/firProblems/kt19251.ir.txt index c19421f21a5..0abc3a64a24 100644 --- a/compiler/testData/ir/irText/firProblems/kt19251.ir.txt +++ b/compiler/testData/ir/irText/firProblems/kt19251.ir.txt @@ -18,10 +18,11 @@ FILE fqName: fileName:/test.kt CALL 'public open fun computeIfAbsent (p0: @[EnhancedNullability] K of kotlin.collections.MutableMap, p1: @[EnhancedNullability] java.util.function.Function): @[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<.Fun, kotlin.String> [val] declared in .box' type=kotlin.collections.MutableMap<.Fun, kotlin.String> origin=null p0: GET_VAR 'val fn: .Fun [val] declared in .box' type=.Fun origin=null - p1: TYPE_OP type=@[EnhancedNullability] java.util.function.Function<@[EnhancedNullability] .Fun, @[EnhancedNullability] kotlin.String> origin=SAM_CONVERSION typeOperand=@[EnhancedNullability] java.util.function.Function<@[EnhancedNullability] .Fun, @[EnhancedNullability] kotlin.String> - FUN_EXPR type=kotlin.Function1<@[EnhancedNullability] .Fun, @[EnhancedNullability] kotlin.String> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:@[EnhancedNullability] .Fun) returnType:@[EnhancedNullability] kotlin.String - VALUE_PARAMETER name:it index:0 type:@[EnhancedNullability] .Fun - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (it: @[EnhancedNullability] .Fun): @[EnhancedNullability] kotlin.String declared in .box' - CONST String type=kotlin.String value="OK" + p1: TYPE_OP type=@[EnhancedNullability] java.util.function.Function origin=SAM_CONVERSION typeOperand=@[EnhancedNullability] java.util.function.Function + 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] .Fun, @[EnhancedNullability] kotlin.String> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:@[EnhancedNullability] .Fun) returnType:@[EnhancedNullability] kotlin.String + VALUE_PARAMETER name:it index:0 type:@[EnhancedNullability] .Fun + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: @[EnhancedNullability] .Fun): @[EnhancedNullability] kotlin.String declared in .box' + CONST String type=kotlin.String value="OK" diff --git a/compiler/testData/ir/irText/firProblems/kt19251.kt.txt b/compiler/testData/ir/irText/firProblems/kt19251.kt.txt index d31ff18091e..e0021e4a349 100644 --- a/compiler/testData/ir/irText/firProblems/kt19251.kt.txt +++ b/compiler/testData/ir/irText/firProblems/kt19251.kt.txt @@ -7,5 +7,5 @@ fun box(): String { return map.computeIfAbsent(p0 = fn, p1 = local fun (it: @EnhancedNullability Fun): @EnhancedNullability String { return "OK" } - /*-> @EnhancedNullability Function<@EnhancedNullability Fun, @EnhancedNullability String> */) /*!! String */ + /*as Function1<@EnhancedNullability Any?, @EnhancedNullability String> */ /*-> @EnhancedNullability Function */) /*!! String */ } diff --git a/compiler/testData/ir/irText/types/intersectionTypeInSamType.ir.txt b/compiler/testData/ir/irText/types/intersectionTypeInSamType.ir.txt index cf1b96526be..7677e4fe3c1 100644 --- a/compiler/testData/ir/irText/types/intersectionTypeInSamType.ir.txt +++ b/compiler/testData/ir/irText/types/intersectionTypeInSamType.ir.txt @@ -196,14 +196,13 @@ FILE fqName: fileName:/intersectionTypeInSamType.kt : .B CALL 'public final fun checkFoo (x: .IFoo.G1>): kotlin.Unit declared in .G1' type=kotlin.Unit origin=null $this: GET_VAR 'val g: .G1<*> [val] declared in .test1' type=.G1<*> origin=null - x: TYPE_OP type=.IFoo<.X> origin=SAM_CONVERSION typeOperand=.IFoo<.X> - TYPE_OP type=kotlin.Function1<@[ParameterName(name = 't')] .X, kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<@[ParameterName(name = 't')] .X, kotlin.Unit> - FUN_EXPR type=kotlin.Function1 origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.Any) returnType:kotlin.Unit - VALUE_PARAMETER name:it index:0 type:kotlin.Any - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (it: kotlin.Any): kotlin.Unit declared in .test1' - GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit + x: TYPE_OP type=.IFoo origin=SAM_CONVERSION typeOperand=.IFoo + FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:it index:0 type:kotlin.Any + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: kotlin.Any): kotlin.Unit declared in .test1' + GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY VAR name:g type:.G2<*> [val] @@ -215,17 +214,16 @@ FILE fqName: fileName:/intersectionTypeInSamType.kt : .B CALL 'public final fun checkFoo (x: .IFoo.G2>): kotlin.Unit declared in .G2' type=kotlin.Unit origin=null $this: GET_VAR 'val g: .G2<*> [val] declared in .test2' type=.G2<*> origin=null - x: TYPE_OP type=.IFoo<.X> origin=SAM_CONVERSION typeOperand=.IFoo<.X> - TYPE_OP type=kotlin.Function1<@[ParameterName(name = 't')] .X, kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<@[ParameterName(name = 't')] .X, kotlin.Unit> - FUN_EXPR type=kotlin.Function1 origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.Any) returnType:kotlin.Unit - VALUE_PARAMETER name:it index:0 type:kotlin.Any - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (it: kotlin.Any): kotlin.Unit declared in .test2' - GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit + x: TYPE_OP type=.IFoo origin=SAM_CONVERSION typeOperand=.IFoo + FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:it index:0 type:kotlin.Any + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: kotlin.Any): kotlin.Unit declared in .test2' + GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit CALL 'public final fun checkBar1 (x: .IBar1.G2>): kotlin.Unit declared in .G2' type=kotlin.Unit origin=null $this: GET_VAR 'val g: .G2<*> [val] declared in .test2' type=.G2<*> origin=null - x: TYPE_OP type=.IBar1<*> origin=SAM_CONVERSION typeOperand=.IBar1<*> + x: TYPE_OP type=.IBar1 origin=SAM_CONVERSION typeOperand=.IBar1 FUN_EXPR type=kotlin.Function1 origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.Any) returnType:kotlin.Unit VALUE_PARAMETER name:it index:0 type:kotlin.Any @@ -234,7 +232,7 @@ FILE fqName: fileName:/intersectionTypeInSamType.kt GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit CALL 'public final fun checkBar2 (x: .IBar2.G2>): kotlin.Unit declared in .G2' type=kotlin.Unit origin=null $this: GET_VAR 'val g: .G2<*> [val] declared in .test2' type=.G2<*> origin=null - x: TYPE_OP type=.IBar2<*> origin=SAM_CONVERSION typeOperand=.IBar2<*> + x: TYPE_OP type=.IBar2 origin=SAM_CONVERSION typeOperand=.IBar2 FUN_EXPR type=kotlin.Function1 origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.Any) returnType:kotlin.Unit VALUE_PARAMETER name:it index:0 type:kotlin.Any diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 92ba364af5f..5b1567b6943 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -26000,6 +26000,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/invokedynamic/sam/kt47510.kt"); } + @Test + @TestMetadata("kt51868_contravariantGenericSam.kt") + public void testKt51868_contravariantGenericSam() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/sam/kt51868_contravariantGenericSam.kt"); + } + @Test @TestMetadata("kt52040_severalProxyFunsInInit.kt") public void testKt52040_severalProxyFunsInInit() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 26b39fd2035..4af22080465 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -26606,6 +26606,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/invokedynamic/sam/kt47510.kt"); } + @Test + @TestMetadata("kt51868_contravariantGenericSam.kt") + public void testKt51868_contravariantGenericSam() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/sam/kt51868_contravariantGenericSam.kt"); + } + @Test @TestMetadata("kt52040_severalProxyFunsInInit.kt") public void testKt52040_severalProxyFunsInInit() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 84904847f7d..13d1e5a5caf 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -21907,6 +21907,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/invokedynamic/sam/kt47510.kt"); } + @TestMetadata("kt51868_contravariantGenericSam.kt") + public void testKt51868_contravariantGenericSam() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/sam/kt51868_contravariantGenericSam.kt"); + } + @TestMetadata("kt52040_severalProxyFunsInInit.kt") public void testKt52040_severalProxyFunsInInit() throws Exception { runTest("compiler/testData/codegen/box/invokedynamic/sam/kt52040_severalProxyFunsInInit.kt");