From 7dc3be3b9b410d439d766c168df07f9854013582 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 18 Mar 2021 12:48:28 +0300 Subject: [PATCH] [FIR2IR] Replace star projections with upper bounds for SAM conversion types --- .../generators/CallAndReferenceGenerator.kt | 21 ++++++++++++++- .../FirBlackBoxCodegenTestGenerated.java | 6 +++++ .../genericWithStarProjection.kt | 1 - .../box/sam/samConversionToJavaWildcard.kt | 26 +++++++++++++++++++ .../sam/samByProjectedType.fir.kt.txt | 7 ----- .../sam/samByProjectedType.fir.txt | 11 -------- .../expressions/sam/samByProjectedType.kt | 1 + .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++++ .../LightAnalysisModeTestGenerated.java | 5 ++++ 10 files changed, 70 insertions(+), 20 deletions(-) create mode 100644 compiler/testData/codegen/box/sam/samConversionToJavaWildcard.kt delete mode 100644 compiler/testData/ir/irText/expressions/sam/samByProjectedType.fir.kt.txt delete mode 100644 compiler/testData/ir/irText/expressions/sam/samByProjectedType.fir.txt diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index ea0ebdded74..37ff1d16a58 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType import org.jetbrains.kotlin.fir.resolve.inference.isKMutableProperty +import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap import org.jetbrains.kotlin.fir.resolve.toSymbol @@ -622,7 +623,8 @@ class CallAndReferenceGenerator( return this } val samFirType = parameter.returnTypeRef.coneTypeSafe()?.let { - val substituted = substitutor.substituteOrSelf(it) + var substituted = substitutor.substituteOrSelf(it) + substituted = starProjectionApproximator.substituteOrSelf(substituted) if (substituted is ConeRawType) substituted.lowerBound else substituted } var samType = samFirType?.toIrType(ConversionTypeContext.WITH_INVARIANT) ?: createErrorType() @@ -634,6 +636,23 @@ class CallAndReferenceGenerator( return IrTypeOperatorCallImpl(this.startOffset, this.endOffset, samType, IrTypeOperator.SAM_CONVERSION, samType, this) } + private val starProjectionApproximator = object : AbstractConeSubstitutor() { + override fun substituteType(type: ConeKotlinType): ConeKotlinType? { + if (type !is ConeClassLikeType || type.typeArguments.none { it == ConeStarProjection }) return null + val fir = type.lookupTag.toSymbol(session)?.fir as? FirTypeParameterRefsOwner ?: return null + val typeParameters = fir.typeParameters.map { it.symbol.fir } + if (typeParameters.size != type.typeArguments.size) return null + val newTypeArguments = typeParameters.zip(type.typeArguments).map { (parameter, argument) -> + if (argument == ConeStarProjection){ + parameter.bounds.first().coneType + } else { + argument + } + } + return type.withArguments(newTypeArguments.toTypedArray()) + } + } + private fun needSamConversion(argument: FirExpression, parameter: FirValueParameter): Boolean { // If the type of the argument is already an explicitly subtype of the type of the parameter, we don't need SAM conversion. if (argument.typeRef !is FirResolvedTypeRef || 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 25c62856109..23183cafede 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 @@ -37440,6 +37440,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/sam/samConstructorGenericSignature.kt"); } + @Test + @TestMetadata("samConversionToJavaWildcard.kt") + public void testSamConversionToJavaWildcard() throws Exception { + runTest("compiler/testData/codegen/box/sam/samConversionToJavaWildcard.kt"); + } + @Test @TestMetadata("smartCastSamConversion.kt") public void testSmartCastSamConversion() throws Exception { diff --git a/compiler/testData/codegen/box/invokedynamic/sam/specializedGenerics/genericWithStarProjection.kt b/compiler/testData/codegen/box/invokedynamic/sam/specializedGenerics/genericWithStarProjection.kt index 84e5e2f6ccb..712f0afbceb 100644 --- a/compiler/testData/codegen/box/invokedynamic/sam/specializedGenerics/genericWithStarProjection.kt +++ b/compiler/testData/codegen/box/invokedynamic/sam/specializedGenerics/genericWithStarProjection.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR // JVM_TARGET: 1.8 // SAM_CONVERSIONS: INDY fun interface Cmp { diff --git a/compiler/testData/codegen/box/sam/samConversionToJavaWildcard.kt b/compiler/testData/codegen/box/sam/samConversionToJavaWildcard.kt new file mode 100644 index 00000000000..f655262a3c3 --- /dev/null +++ b/compiler/testData/codegen/box/sam/samConversionToJavaWildcard.kt @@ -0,0 +1,26 @@ +// TARGET_BACKEND: JVM +// FULL_JDK +// FILE: ConventionMapping.java +import java.util.concurrent.Callable; + +public class ConventionMapping { + MappedProperty map(String propertyName, Callable value) { + return new MappedProperty(); + } + + public static class MappedProperty { + + } +} + +// FILE: FileCollection.java + +public class FileCollection {} + +// FILE: test.kt + +fun test(mapping: ConventionMapping, fn: () -> FileCollection) { + mapping.map("classpath", fn) +} + +fun box(): String = "OK" diff --git a/compiler/testData/ir/irText/expressions/sam/samByProjectedType.fir.kt.txt b/compiler/testData/ir/irText/expressions/sam/samByProjectedType.fir.kt.txt deleted file mode 100644 index bb67b196c0b..00000000000 --- a/compiler/testData/ir/irText/expressions/sam/samByProjectedType.fir.kt.txt +++ /dev/null @@ -1,7 +0,0 @@ -fun test1() { - bar(j = local fun (x: Any): @FlexibleNullability Any? { - return x - } - /*-> @FlexibleNullability J<*>? */) -} - diff --git a/compiler/testData/ir/irText/expressions/sam/samByProjectedType.fir.txt b/compiler/testData/ir/irText/expressions/sam/samByProjectedType.fir.txt deleted file mode 100644 index 241f21e15c8..00000000000 --- a/compiler/testData/ir/irText/expressions/sam/samByProjectedType.fir.txt +++ /dev/null @@ -1,11 +0,0 @@ -FILE fqName: fileName:/samByProjectedType.kt - FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit - BLOCK_BODY - CALL 'public open fun bar (j: @[FlexibleNullability] .J<*>?): kotlin.Unit declared in .H' type=kotlin.Unit origin=null - j: TYPE_OP type=@[FlexibleNullability] .J<*>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] .J<*>? - FUN_EXPR type=kotlin.Function1 origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (x:kotlin.Any) returnType:@[FlexibleNullability] kotlin.Any? - VALUE_PARAMETER name:x index:0 type:kotlin.Any - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (x: kotlin.Any): @[FlexibleNullability] kotlin.Any? declared in .test1' - GET_VAR 'x: kotlin.Any declared in .test1.' type=kotlin.Any origin=null diff --git a/compiler/testData/ir/irText/expressions/sam/samByProjectedType.kt b/compiler/testData/ir/irText/expressions/sam/samByProjectedType.kt index e258f23d999..1aa575fefc0 100644 --- a/compiler/testData/ir/irText/expressions/sam/samByProjectedType.kt +++ b/compiler/testData/ir/irText/expressions/sam/samByProjectedType.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // FILE: samByProjectedType.kt fun test1() { H.bar { x: Any -> x } 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 bcdc974af52..bb8cb864e26 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 @@ -37440,6 +37440,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/sam/samConstructorGenericSignature.kt"); } + @Test + @TestMetadata("samConversionToJavaWildcard.kt") + public void testSamConversionToJavaWildcard() throws Exception { + runTest("compiler/testData/codegen/box/sam/samConversionToJavaWildcard.kt"); + } + @Test @TestMetadata("smartCastSamConversion.kt") public void testSmartCastSamConversion() 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 411e14995c4..00c7aa7c832 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 @@ -37440,6 +37440,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/sam/samConstructorGenericSignature.kt"); } + @Test + @TestMetadata("samConversionToJavaWildcard.kt") + public void testSamConversionToJavaWildcard() throws Exception { + runTest("compiler/testData/codegen/box/sam/samConversionToJavaWildcard.kt"); + } + @Test @TestMetadata("smartCastSamConversion.kt") public void testSmartCastSamConversion() 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 5ff075730f1..89fc6f17cec 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -29842,6 +29842,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/sam/samConstructorGenericSignature.kt"); } + @TestMetadata("samConversionToJavaWildcard.kt") + public void testSamConversionToJavaWildcard() throws Exception { + runTest("compiler/testData/codegen/box/sam/samConversionToJavaWildcard.kt"); + } + @TestMetadata("smartCastSamConversion.kt") public void testSmartCastSamConversion() throws Exception { runTest("compiler/testData/codegen/box/sam/smartCastSamConversion.kt");