From 9a3b5e547bd3308322998ec1acfbf2a53bce2ca4 Mon Sep 17 00:00:00 2001 From: Victor Petukhov Date: Thu, 5 May 2022 17:52:17 +0200 Subject: [PATCH] [FE] Add fast-paths for some types which are checked for intersection emptiness --- .../kotlin/types/model/TypeSystemContext.kt | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt index f32678c28a7..128a231ee48 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt @@ -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