From 36f21932bb0978a2953621476b6411e3d4e3b0e1 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 27 Jan 2016 14:39:35 +0300 Subject: [PATCH] Approximate captured type before mapping #KT-7415 Fixed --- .../kotlin/codegen/ExpressionCodegen.java | 9 ++++---- .../reified/approximateCapturedTypes.kt | 21 +++++++++++++++++++ ...lackBoxWithStdlibCodegenTestGenerated.java | 6 ++++++ .../org/jetbrains/kotlin/types/TypeUtils.java | 15 ------------- 4 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/reified/approximateCapturedTypes.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 28f9a48719a..cddaf7f20bc 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -83,6 +83,7 @@ import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.TypeProjection; import org.jetbrains.kotlin.types.TypeUtils; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; +import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt; import org.jetbrains.org.objectweb.asm.Label; import org.jetbrains.org.objectweb.asm.MethodVisitor; import org.jetbrains.org.objectweb.asm.Opcodes; @@ -2452,19 +2453,19 @@ public class ExpressionCodegen extends KtVisitor impleme TypeParameterMappings mappings = new TypeParameterMappings(); for (Map.Entry entry : typeArguments.entrySet()) { TypeParameterDescriptor key = entry.getKey(); - - KotlinType type = TypeUtils.uncaptureTypeForInlineMapping(entry.getValue()); + KotlinType type = entry.getValue(); boolean isReified = key.isReified() || InlineUtil.isArrayConstructorWithLambda(resolvedCall.getResultingDescriptor()); Pair typeParameterAndReificationArgument = extractReificationArgument(type); if (typeParameterAndReificationArgument == null) { + KotlinType approximatedType = CapturedTypeApproximationKt.approximateCapturedTypes(entry.getValue()).getUpper(); // type is not generic BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE); - Type asmType = typeMapper.mapTypeParameter(type, signatureWriter); + Type asmType = typeMapper.mapTypeParameter(approximatedType, signatureWriter); mappings.addParameterMappingToType( - key.getName().getIdentifier(), type, asmType, signatureWriter.toString(), isReified + key.getName().getIdentifier(), approximatedType, asmType, signatureWriter.toString(), isReified ); } else { diff --git a/compiler/testData/codegen/boxWithStdlib/reified/approximateCapturedTypes.kt b/compiler/testData/codegen/boxWithStdlib/reified/approximateCapturedTypes.kt new file mode 100644 index 00000000000..1731a9a6d62 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reified/approximateCapturedTypes.kt @@ -0,0 +1,21 @@ +// Basically this test checks that no captured type used as argument for signature mapping +class SwOperator: Operator, T> + +interface Operator + +open class Inv + +class Obs { + inline fun lift(lift: Operator) = object : Inv() {} +} + +fun box(): String { + val o: Obs = Obs() + + val inv = o.lift(SwOperator()) + val signature = inv.javaClass.genericSuperclass.toString() + + if (signature != "Inv>") return "fail 1: $signature" + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 0f6577f31fe..bb43e22afaa 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -4555,6 +4555,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("approximateCapturedTypes.kt") + public void testApproximateCapturedTypes() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/approximateCapturedTypes.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("checkcast.kt") public void testCheckcast() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/checkcast.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java index 1933750c197..485d8aabf44 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java @@ -26,11 +26,9 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor; import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.resolve.calls.inference.CapturedType; -import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructor; import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor; import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; -import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt; import java.util.*; @@ -509,19 +507,6 @@ public class TypeUtils { return typeParameterDescriptor != null && typeParameterDescriptor.isReified(); } - @NotNull - public static KotlinType uncaptureTypeForInlineMapping(@NotNull KotlinType type) { - TypeConstructor constructor = type.getConstructor(); - if (constructor instanceof CapturedTypeConstructor) { - TypeProjection projection = ((CapturedTypeConstructor) constructor).getTypeProjection(); - if (Variance.IN_VARIANCE == projection.getProjectionKind()) { - //in variance could be captured only for or declarations - return TypeUtilsKt.getBuiltIns(type).getNullableAnyType(); - } - return uncaptureTypeForInlineMapping(projection.getType()); - } - return type; - } @Nullable public static TypeParameterDescriptor getTypeParameterDescriptorOrNull(@NotNull KotlinType type) { if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {