Avoid subtype checking between type variable of self type and captured star projection only for invariant positions
Subtyping with non-invariant positions may produce useful constraints ^KT-46001 Fixed
This commit is contained in:
+12
@@ -11913,6 +11913,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/dependantOnVarianceNullable.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/dependantOnVarianceNullable.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("discardInapplicableCandidateWithNotSatisfyingSelfType.kt")
|
||||||
|
public void testDiscardInapplicableCandidateWithNotSatisfyingSelfType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/discardInapplicableCandidateWithNotSatisfyingSelfType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("equalitySubstitutionInsideNonInvariantType.kt")
|
@TestMetadata("equalitySubstitutionInsideNonInvariantType.kt")
|
||||||
public void testEqualitySubstitutionInsideNonInvariantType() throws Exception {
|
public void testEqualitySubstitutionInsideNonInvariantType() throws Exception {
|
||||||
@@ -12387,6 +12393,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/useFunctionLiteralsToInferType.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/useFunctionLiteralsToInferType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("violatingUpperBoundForSelfType.kt")
|
||||||
|
public void testViolatingUpperBoundForSelfType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/violatingUpperBoundForSelfType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference")
|
@TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
interface WithChildren<out T>
|
||||||
|
|
||||||
|
fun <T : WithChildren<*>> WithChildren<WithChildren<*>>.test() {
|
||||||
|
withDescendants()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : WithChildren<T>> T.withDescendants() {}
|
||||||
|
|
||||||
|
@JvmName("foo")
|
||||||
|
fun WithChildren<*>.withDescendants() {}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ T : WithChildren<*>> WithChildren<WithChildren<*>>.test(): kotlin.Unit
|
||||||
|
public fun </*0*/ T : WithChildren<T>> T.withDescendants(): kotlin.Unit
|
||||||
|
@kotlin.jvm.JvmName(name = "foo") public fun WithChildren<*>.withDescendants(): kotlin.Unit
|
||||||
|
|
||||||
|
public interface WithChildren</*0*/ out T> {
|
||||||
|
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
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -CAST_NEVER_SUCCEEDS
|
||||||
|
|
||||||
|
fun <E : Enum<E>> createMap(enumClass: Class<E>) {}
|
||||||
|
|
||||||
|
fun reproduce() {
|
||||||
|
val enumClass: Class<Enum<*>> = "any" as Class<Enum<*>>
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>createMap<!>(enumClass)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -CAST_NEVER_SUCCEEDS
|
||||||
|
|
||||||
|
fun <E : Enum<E>> createMap(enumClass: Class<E>) {}
|
||||||
|
|
||||||
|
fun reproduce() {
|
||||||
|
val enumClass: Class<Enum<*>> = "any" as Class<Enum<*>>
|
||||||
|
createMap(<!TYPE_MISMATCH, TYPE_MISMATCH!>enumClass<!>)
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ E : kotlin.Enum<E>> createMap(/*0*/ enumClass: java.lang.Class<E>): kotlin.Unit
|
||||||
|
public fun reproduce(): kotlin.Unit
|
||||||
Generated
+12
@@ -11919,6 +11919,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/dependantOnVarianceNullable.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/dependantOnVarianceNullable.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("discardInapplicableCandidateWithNotSatisfyingSelfType.kt")
|
||||||
|
public void testDiscardInapplicableCandidateWithNotSatisfyingSelfType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/discardInapplicableCandidateWithNotSatisfyingSelfType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("equalitySubstitutionInsideNonInvariantType.kt")
|
@TestMetadata("equalitySubstitutionInsideNonInvariantType.kt")
|
||||||
public void testEqualitySubstitutionInsideNonInvariantType() throws Exception {
|
public void testEqualitySubstitutionInsideNonInvariantType() throws Exception {
|
||||||
@@ -12393,6 +12399,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/useFunctionLiteralsToInferType.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/useFunctionLiteralsToInferType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("violatingUpperBoundForSelfType.kt")
|
||||||
|
public void testViolatingUpperBoundForSelfType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/violatingUpperBoundForSelfType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference")
|
@TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
@@ -406,9 +406,13 @@ object AbstractTypeChecker {
|
|||||||
it.getType()
|
it.getType()
|
||||||
}
|
}
|
||||||
|
|
||||||
val isTypeVariableAgainstStarProjectionForSelfType =
|
val variance = effectiveVariance(superTypeConstructor.getParameter(index).getVariance(), superProjection.getVariance())
|
||||||
|
?: return isErrorTypeEqualsToAnything // todo exception?
|
||||||
|
|
||||||
|
val isTypeVariableAgainstStarProjectionForSelfType = if (variance == TypeVariance.INV) {
|
||||||
isTypeVariableAgainstStarProjectionForSelfType(subArgumentType, superArgumentType, superTypeConstructor) ||
|
isTypeVariableAgainstStarProjectionForSelfType(subArgumentType, superArgumentType, superTypeConstructor) ||
|
||||||
isTypeVariableAgainstStarProjectionForSelfType(superArgumentType, subArgumentType, superTypeConstructor)
|
isTypeVariableAgainstStarProjectionForSelfType(superArgumentType, subArgumentType, superTypeConstructor)
|
||||||
|
} else false
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't check subtyping between types like CapturedType(*) and TypeVariable(E) if the corresponding type parameter forms self type, for instance, Enum<E: Enum<E>>.
|
* We don't check subtyping between types like CapturedType(*) and TypeVariable(E) if the corresponding type parameter forms self type, for instance, Enum<E: Enum<E>>.
|
||||||
@@ -417,10 +421,8 @@ object AbstractTypeChecker {
|
|||||||
* Instead this type check we move on self-type level anyway: checking CapturedType(out Enum<*>) against TypeVariable(E).
|
* Instead this type check we move on self-type level anyway: checking CapturedType(out Enum<*>) against TypeVariable(E).
|
||||||
* This subtyping can already be successful and not add unwanted constraints in the type inference context.
|
* This subtyping can already be successful and not add unwanted constraints in the type inference context.
|
||||||
*/
|
*/
|
||||||
if (isTypeVariableAgainstStarProjectionForSelfType) continue
|
if (isTypeVariableAgainstStarProjectionForSelfType)
|
||||||
|
continue
|
||||||
val variance = effectiveVariance(superTypeConstructor.getParameter(index).getVariance(), superProjection.getVariance())
|
|
||||||
?: return isErrorTypeEqualsToAnything // todo exception?
|
|
||||||
|
|
||||||
val correctArgument = runWithArgumentsSettings(subArgumentType) {
|
val correctArgument = runWithArgumentsSettings(subArgumentType) {
|
||||||
when (variance) {
|
when (variance) {
|
||||||
|
|||||||
Reference in New Issue
Block a user