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.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<StackValue, StackValue> impleme
|
||||
TypeParameterMappings mappings = new TypeParameterMappings();
|
||||
for (Map.Entry<TypeParameterDescriptor, KotlinType> 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<TypeParameterDescriptor, ReificationArgument> 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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@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");
|
||||
|
||||
@@ -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 <T> or <T: Any?> 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) {
|
||||
|
||||
Reference in New Issue
Block a user