[FE] Add fast-paths for some types which are checked for intersection emptiness

This commit is contained in:
Victor Petukhov
2022-05-05 17:52:17 +02:00
committed by teamcity
parent 02a430875f
commit 9a3b5e547b
@@ -329,16 +329,20 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
for (i in 0 until types.size) {
val firstType = types[i]
if (!firstType.mayCauseEmptyIntersection()) continue
val firstSubstitutedType by lazy { firstType.eraseContainingTypeParameters() }
for (j in i + 1 until types.size) {
val secondType = types[j]
if (!secondType.mayCauseEmptyIntersection()) continue
val secondSubstitutedType = secondType.eraseContainingTypeParameters()
if (!secondSubstitutedType.mayCauseEmptyIntersection() && !firstSubstitutedType.mayCauseEmptyIntersection()) continue
if (!canHaveCommonSubtype(firstSubstitutedType, secondSubstitutedType))
return EmptyIntersectionTypeKind.MULTIPLE_CLASSES
}
@@ -415,7 +419,7 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
} else listOf(type)
val expandedTypes = extractIntersectionComponentsIfNeeded(first) + extractIntersectionComponentsIfNeeded(second)
val typeCheckerState = newTypeCheckerState(errorTypesEqualToAnything = true, stubTypesEqualToAnything = true)
val typeCheckerState by lazy { newTypeCheckerState(errorTypesEqualToAnything = true, stubTypesEqualToAnything = true) }
for (i in expandedTypes.indices) {
val firstType = expandedTypes[i].withNullability(false)
@@ -437,6 +441,12 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
if (AbstractTypeChecker.areRelatedBySubtyping(this, firstType, secondType))
continue
// If two classes aren't related by subtyping and no need to compare their type arguments, then they can't have a common subtype
if (
firstTypeConstructor.isDefinitelyClassTypeConstructor() && secondTypeConstructor.isDefinitelyClassTypeConstructor()
&& (firstTypeConstructor.parametersCount() == 0 || secondTypeConstructor.parametersCount() == 0)
) return false
val superTypeByFirstConstructor = AbstractTypeChecker.findCorrespondingSupertypes(
typeCheckerState, firstType.lowerBoundIfFlexible(), secondTypeConstructor
).singleOrNull()
@@ -454,7 +464,7 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
return false
if (superTypeByFirstConstructor == null || superTypeBySecondConstructor == null)
continue // first or second is actually subtype of another
continue // don't have incompatible supertypes so can have a common subtype
if (!checkArgumentsOfTypesToBeAbleToHaveCommonSubtype(superTypeByFirstConstructor, superTypeBySecondConstructor))
return false
@@ -657,6 +667,8 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
fun KotlinTypeMarker.lowerBoundIfFlexible(): SimpleTypeMarker = this.asFlexibleType()?.lowerBound() ?: this.asSimpleType()!!
fun KotlinTypeMarker.upperBoundIfFlexible(): SimpleTypeMarker = this.asFlexibleType()?.upperBound() ?: this.asSimpleType()!!
fun TypeConstructorMarker.isDefinitelyClassTypeConstructor(): Boolean = isClassTypeConstructor() && !isInterface()
fun KotlinTypeMarker.isFlexible(): Boolean = asFlexibleType() != null
fun KotlinTypeMarker.isDynamic(): Boolean = asFlexibleType()?.asDynamicType() != null