EmptyIntersectionTypeChecker: drop also incompatible supertypes check
Incompatible supertypes check also don't provoke runtime problems in most situations, because this check is also bound to type argument conflict. Related to KT-54411
This commit is contained in:
committed by
Space Team
parent
29ad5f981c
commit
758a4931e3
Vendored
-16
@@ -1,16 +0,0 @@
|
||||
class Foo<T>
|
||||
|
||||
class Bar<T> {
|
||||
fun <S : T> takeFoo(foo: Foo<in S>) {}
|
||||
}
|
||||
|
||||
class Out<out P>
|
||||
|
||||
interface A<K>
|
||||
interface B<T> : A<T>
|
||||
interface C<T> : A<T>
|
||||
|
||||
fun <K : C<Int>> main() {
|
||||
val foo = Foo<K>()
|
||||
Bar<B<String>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
}
|
||||
Vendored
+2
-1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class Foo<T>
|
||||
|
||||
class Bar<T> {
|
||||
@@ -12,5 +13,5 @@ interface C<T> : A<T>
|
||||
|
||||
fun <K : C<Int>> main() {
|
||||
val foo = Foo<K>()
|
||||
Bar<B<String>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
Bar<B<String>>().takeFoo(foo) // error in 1.3.72, no error in 1.4.31
|
||||
}
|
||||
|
||||
Vendored
-18
@@ -1,18 +0,0 @@
|
||||
class Foo<T>
|
||||
|
||||
class Bar<T> {
|
||||
fun <S : T> takeFoo(foo: Foo<in S>) {}
|
||||
}
|
||||
|
||||
class Out<out P>
|
||||
|
||||
interface A<K>
|
||||
interface B2<T> : A<T>
|
||||
interface C2<T> : A<T>
|
||||
interface B<T> : B2<T>
|
||||
interface C<T> : C2<T>
|
||||
|
||||
fun <K : C<Int>> main() {
|
||||
val foo = Foo<K>()
|
||||
Bar<B<String>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
}
|
||||
Vendored
+2
-1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class Foo<T>
|
||||
|
||||
class Bar<T> {
|
||||
@@ -14,5 +15,5 @@ interface C<T> : C2<T>
|
||||
|
||||
fun <K : C<Int>> main() {
|
||||
val foo = Foo<K>()
|
||||
Bar<B<String>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
|
||||
Bar<B<String>>().takeFoo(foo) // error in 1.3.72, no error in 1.4.31
|
||||
}
|
||||
|
||||
-54
@@ -101,10 +101,6 @@ internal object EmptyIntersectionTypeChecker {
|
||||
return EmptyIntersectionTypeInfo(EmptyIntersectionTypeKind.MULTIPLE_CLASSES, firstType, secondType)
|
||||
}
|
||||
firstTypeConstructor.isFinalClassConstructor() || secondTypeConstructor.isFinalClassConstructor() -> {
|
||||
val incompatibleSupertypes = getIncompatibleSuperTypes(firstType, secondType)
|
||||
if (incompatibleSupertypes != null) {
|
||||
return EmptyIntersectionTypeInfo(EmptyIntersectionTypeKind.INCOMPATIBLE_SUPERTYPES, *incompatibleSupertypes)
|
||||
}
|
||||
// don't have incompatible supertypes so can have a common subtype only if all types are interfaces
|
||||
possibleEmptyIntersectionKind = EmptyIntersectionTypeInfo(
|
||||
EmptyIntersectionTypeKind.FINAL_CLASS_AND_INTERFACE,
|
||||
@@ -125,56 +121,6 @@ internal object EmptyIntersectionTypeChecker {
|
||||
typeCheckerState, this, otherConstructorMarker
|
||||
).isNotEmpty()
|
||||
|
||||
private fun TypeSystemInferenceExtensionContext.getIncompatibleSuperTypes(
|
||||
firstType: KotlinTypeMarker, secondType: KotlinTypeMarker
|
||||
): Array<KotlinTypeMarker>? {
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val firstType = firstType.eraseContainingTypeParameters()
|
||||
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val secondType = secondType.eraseContainingTypeParameters()
|
||||
|
||||
// interface A<K>
|
||||
// interface B: A<String>
|
||||
// interface C: A<Int>
|
||||
// => B and C have incompatible supertypes
|
||||
val superTypesOfFirst = firstType.typeConstructor().supertypes()
|
||||
val firstTypeSubstitutor = createSubstitutorForSuperTypes(firstType)
|
||||
val superTypesOfSecond = secondType.typeConstructor().supertypes()
|
||||
val secondTypeSubstitutor = createSubstitutorForSuperTypes(secondType)
|
||||
|
||||
for (superTypeOfFirst in superTypesOfFirst) {
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val superTypeOfFirst = firstTypeSubstitutor?.safeSubstitute(superTypeOfFirst) ?: superTypeOfFirst
|
||||
|
||||
if (areIncompatibleSuperTypes(superTypeOfFirst, secondType))
|
||||
return arrayOf(superTypeOfFirst, secondType)
|
||||
|
||||
for (superTypeOfSecond in superTypesOfSecond) {
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val superTypeOfSecond = secondTypeSubstitutor?.safeSubstitute(superTypeOfSecond) ?: superTypeOfSecond
|
||||
|
||||
if (areIncompatibleSuperTypes(firstType, superTypeOfSecond))
|
||||
return arrayOf(firstType, superTypeOfSecond)
|
||||
|
||||
if (areIncompatibleSuperTypes(superTypeOfFirst, superTypeOfSecond))
|
||||
return arrayOf(superTypeOfFirst, superTypeOfSecond)
|
||||
|
||||
getIncompatibleSuperTypes(superTypeOfFirst, superTypeOfSecond)?.let { return it }
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun TypeSystemInferenceExtensionContext.areIncompatibleSuperTypes(
|
||||
firstType: KotlinTypeMarker, secondType: KotlinTypeMarker
|
||||
): Boolean = firstType.typeConstructor() == secondType.typeConstructor()
|
||||
&& !AbstractTypeChecker.equalTypes(
|
||||
newTypeCheckerState(errorTypesEqualToAnything = true, stubTypesEqualToAnything = true),
|
||||
firstType, secondType
|
||||
)
|
||||
|
||||
private fun TypeSystemInferenceExtensionContext.mayCauseEmptyIntersection(type: KotlinTypeMarker): Boolean {
|
||||
val typeConstructor = type.typeConstructor()
|
||||
|
||||
|
||||
@@ -7,6 +7,5 @@ package org.jetbrains.kotlin.types
|
||||
|
||||
enum class EmptyIntersectionTypeKind(val description: String, val isDefinitelyEmpty: Boolean) {
|
||||
MULTIPLE_CLASSES("multiple incompatible classes", isDefinitelyEmpty = true),
|
||||
INCOMPATIBLE_SUPERTYPES("incompatible supertypes", isDefinitelyEmpty = true),
|
||||
FINAL_CLASS_AND_INTERFACE("final class and interface", isDefinitelyEmpty = false)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user