Use "Any?" as out-type for type parameters instead of intersection of bounds
Also refactor checkSubtypeForTheSameConstructor to compute everything in the best order
This commit is contained in:
compiler/testData/diagnostics/tests/subtyping/invariantArgumentForTypeParameterWithMultipleBounds.kt
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
import java.io.Serializable
|
||||
|
||||
class A<T> where T : Cloneable, T : Serializable
|
||||
|
||||
interface CS1 : Cloneable, Serializable
|
||||
interface CS2 : CS1
|
||||
|
||||
interface I1 {
|
||||
fun foo(): A<in CS2>
|
||||
}
|
||||
|
||||
interface I2 : I1 {
|
||||
override fun foo(): A<CS1>
|
||||
}
|
||||
|
||||
interface I3 : I1 {
|
||||
override fun foo(): A<in CS1>
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package
|
||||
|
||||
public final class A</*0*/ T : kotlin.Cloneable> where T : java.io.Serializable {
|
||||
public constructor A</*0*/ T : kotlin.Cloneable>() where T : java.io.Serializable
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface CS1 : kotlin.Cloneable, java.io.Serializable {
|
||||
protected open override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface CS2 : CS1 {
|
||||
protected open override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface I1 {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public abstract fun foo(): A<in CS2>
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface I2 : I1 {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public abstract override /*1*/ fun foo(): A<CS1>
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface I3 : I1 {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public abstract override /*1*/ fun foo(): A<in CS1>
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -15657,6 +15657,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("invariantArgumentForTypeParameterWithMultipleBounds.kt")
|
||||
public void testInvariantArgumentForTypeParameterWithMultipleBounds() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/subtyping/invariantArgumentForTypeParameterWithMultipleBounds.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt2069.kt")
|
||||
public void testKt2069() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/subtyping/kt2069.kt");
|
||||
|
||||
+26
-20
@@ -20,9 +20,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.types.Variance.*;
|
||||
@@ -43,12 +46,14 @@ public class TypeCheckingProcedure {
|
||||
return UtilsKt.findCorrespondingSupertype(subtype, supertype, typeCheckingProcedureCallbacks);
|
||||
}
|
||||
|
||||
public static KotlinType getOutType(TypeParameterDescriptor parameter, TypeProjection argument) {
|
||||
boolean isOutProjected = argument.getProjectionKind() == IN_VARIANCE || parameter.getVariance() == IN_VARIANCE;
|
||||
return isOutProjected ? parameter.getUpperBoundsAsType() : argument.getType();
|
||||
@NotNull
|
||||
private static KotlinType getOutType(@NotNull TypeParameterDescriptor parameter, @NotNull TypeProjection argument) {
|
||||
boolean isInProjected = argument.getProjectionKind() == IN_VARIANCE || parameter.getVariance() == IN_VARIANCE;
|
||||
return isInProjected ? DescriptorUtilsKt.getBuiltIns(parameter).getNullableAnyType() : argument.getType();
|
||||
}
|
||||
|
||||
public static KotlinType getInType(@NotNull TypeParameterDescriptor parameter, @NotNull TypeProjection argument) {
|
||||
@NotNull
|
||||
private static KotlinType getInType(@NotNull TypeParameterDescriptor parameter, @NotNull TypeProjection argument) {
|
||||
boolean isOutProjected = argument.getProjectionKind() == OUT_VARIANCE || parameter.getVariance() == OUT_VARIANCE;
|
||||
return isOutProjected ? DescriptorUtilsKt.getBuiltIns(parameter).getNothingType() : argument.getType();
|
||||
}
|
||||
@@ -229,30 +234,31 @@ public class TypeCheckingProcedure {
|
||||
TypeParameterDescriptor parameter = parameters.get(i);
|
||||
|
||||
TypeProjection superArgument = superArguments.get(i);
|
||||
if (superArgument.isStarProjection()) continue;
|
||||
|
||||
KotlinType superIn = getInType(parameter, superArgument);
|
||||
KotlinType superOut = getOutType(parameter, superArgument);
|
||||
|
||||
TypeProjection subArgument = subArguments.get(i);
|
||||
KotlinType subIn = getInType(parameter, subArgument);
|
||||
KotlinType subOut = getOutType(parameter, subArgument);
|
||||
|
||||
if (superArgument.isStarProjection()) continue;
|
||||
|
||||
if (capture(subArgument, superArgument, parameter)) continue;
|
||||
|
||||
boolean argumentIsErrorType = subArgument.getType().isError() || superArgument.getType().isError();
|
||||
if (!argumentIsErrorType && parameter.getVariance() == INVARIANT
|
||||
&& subArgument.getProjectionKind() == INVARIANT && superArgument.getProjectionKind() == INVARIANT) {
|
||||
if (!argumentIsErrorType && parameter.getVariance() == INVARIANT &&
|
||||
subArgument.getProjectionKind() == INVARIANT && superArgument.getProjectionKind() == INVARIANT) {
|
||||
if (!constraints.assertEqualTypes(subArgument.getType(), superArgument.getType(), this)) return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
KotlinType superOut = getOutType(parameter, superArgument);
|
||||
KotlinType subOut = getOutType(parameter, subArgument);
|
||||
if (!constraints.assertSubtype(subOut, superOut, this)) return false;
|
||||
|
||||
KotlinType superIn = getInType(parameter, superArgument);
|
||||
KotlinType subIn = getInType(parameter, subArgument);
|
||||
|
||||
if (superArgument.getProjectionKind() != Variance.OUT_VARIANCE) {
|
||||
if (!constraints.assertSubtype(superIn, subIn, this)) return false;
|
||||
}
|
||||
else {
|
||||
if (!constraints.assertSubtype(subOut, superOut, this)) return false;
|
||||
if (superArgument.getProjectionKind() != Variance.OUT_VARIANCE) {
|
||||
if (!constraints.assertSubtype(superIn, subIn, this)) return false;
|
||||
}
|
||||
else {
|
||||
assert KotlinBuiltIns.isNothing(superIn) : "In component must be Nothing for out-projection";
|
||||
}
|
||||
assert KotlinBuiltIns.isNothing(superIn) : "In component must be Nothing for out-projection";
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user