Approximate captured type before mapping
#KT-7415 Fixed
This commit is contained in:
@@ -83,6 +83,7 @@ import org.jetbrains.kotlin.types.KotlinType;
|
|||||||
import org.jetbrains.kotlin.types.TypeProjection;
|
import org.jetbrains.kotlin.types.TypeProjection;
|
||||||
import org.jetbrains.kotlin.types.TypeUtils;
|
import org.jetbrains.kotlin.types.TypeUtils;
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
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.Label;
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||||
@@ -2452,19 +2453,19 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
TypeParameterMappings mappings = new TypeParameterMappings();
|
TypeParameterMappings mappings = new TypeParameterMappings();
|
||||||
for (Map.Entry<TypeParameterDescriptor, KotlinType> entry : typeArguments.entrySet()) {
|
for (Map.Entry<TypeParameterDescriptor, KotlinType> entry : typeArguments.entrySet()) {
|
||||||
TypeParameterDescriptor key = entry.getKey();
|
TypeParameterDescriptor key = entry.getKey();
|
||||||
|
KotlinType type = entry.getValue();
|
||||||
KotlinType type = TypeUtils.uncaptureTypeForInlineMapping(entry.getValue());
|
|
||||||
|
|
||||||
boolean isReified = key.isReified() || InlineUtil.isArrayConstructorWithLambda(resolvedCall.getResultingDescriptor());
|
boolean isReified = key.isReified() || InlineUtil.isArrayConstructorWithLambda(resolvedCall.getResultingDescriptor());
|
||||||
|
|
||||||
Pair<TypeParameterDescriptor, ReificationArgument> typeParameterAndReificationArgument = extractReificationArgument(type);
|
Pair<TypeParameterDescriptor, ReificationArgument> typeParameterAndReificationArgument = extractReificationArgument(type);
|
||||||
if (typeParameterAndReificationArgument == null) {
|
if (typeParameterAndReificationArgument == null) {
|
||||||
|
KotlinType approximatedType = CapturedTypeApproximationKt.approximateCapturedTypes(entry.getValue()).getUpper();
|
||||||
// type is not generic
|
// type is not generic
|
||||||
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE);
|
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE);
|
||||||
Type asmType = typeMapper.mapTypeParameter(type, signatureWriter);
|
Type asmType = typeMapper.mapTypeParameter(approximatedType, signatureWriter);
|
||||||
|
|
||||||
mappings.addParameterMappingToType(
|
mappings.addParameterMappingToType(
|
||||||
key.getName().getIdentifier(), type, asmType, signatureWriter.toString(), isReified
|
key.getName().getIdentifier(), approximatedType, asmType, signatureWriter.toString(), isReified
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// Basically this test checks that no captured type used as argument for signature mapping
|
||||||
|
class SwOperator<T>: Operator<List<T>, T>
|
||||||
|
|
||||||
|
interface Operator<R, T>
|
||||||
|
|
||||||
|
open class Inv<T>
|
||||||
|
|
||||||
|
class Obs<Y> {
|
||||||
|
inline fun <reified X> lift(lift: Operator<out X, in Y>) = object : Inv<X>() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val o: Obs<CharSequence> = Obs()
|
||||||
|
|
||||||
|
val inv = o.lift(SwOperator())
|
||||||
|
val signature = inv.javaClass.genericSuperclass.toString()
|
||||||
|
|
||||||
|
if (signature != "Inv<java.util.List<?>>") return "fail 1: $signature"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+6
@@ -4555,6 +4555,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
|||||||
doTestWithStdlib(fileName);
|
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")
|
@TestMetadata("checkcast.kt")
|
||||||
public void testCheckcast() throws Exception {
|
public void testCheckcast() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/checkcast.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/checkcast.kt");
|
||||||
|
|||||||
@@ -26,11 +26,9 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
|||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType;
|
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.constants.IntegerValueTypeConstructor;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
||||||
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -509,19 +507,6 @@ public class TypeUtils {
|
|||||||
return typeParameterDescriptor != null && typeParameterDescriptor.isReified();
|
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 <T> or <T: Any?> declarations
|
|
||||||
return TypeUtilsKt.getBuiltIns(type).getNullableAnyType();
|
|
||||||
}
|
|
||||||
return uncaptureTypeForInlineMapping(projection.getType());
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static TypeParameterDescriptor getTypeParameterDescriptorOrNull(@NotNull KotlinType type) {
|
public static TypeParameterDescriptor getTypeParameterDescriptorOrNull(@NotNull KotlinType type) {
|
||||||
if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
|
if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
|
||||||
|
|||||||
Reference in New Issue
Block a user