From 8d2d5ea211de4c4bcd346862f1a7d72fe5ff9137 Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Wed, 10 Aug 2016 19:51:52 +0300 Subject: [PATCH] Minor refactoring in NewKotlinTypeChecker --- .../types/checker/NewKotlinTypeChecker.kt | 19 +++++++++++-------- .../types/checker/TypeCheckerContext.kt | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewKotlinTypeChecker.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewKotlinTypeChecker.kt index 68d8bf1d9ae..462697de3f0 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewKotlinTypeChecker.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewKotlinTypeChecker.kt @@ -88,11 +88,16 @@ object NewKotlinTypeChecker : KotlinTypeChecker { return isSubtypeOf(a, b) && isSubtypeOf(b, a) } - fun TypeCheckerContext.isSubtypeOf(subType: UnwrappedType, superType: UnwrappedType) = - isSubtypeOf(subType.lowerIfFlexible(), superType.upperIfFlexible()) + fun TypeCheckerContext.isSubtypeOf(subType: UnwrappedType, superType: UnwrappedType): Boolean { + val newSubType = transformToNewType(subType) + val newSuperType = transformToNewType(superType) - fun TypeCheckerContext.isSubtypeOf(subType: SimpleType, superType: SimpleType): Boolean { - return isSubtypeOfForNewTypes(transformToNewType(subType), transformToNewType(superType)) + checkSubtypeForSpecialCases(newSubType.lowerIfFlexible(), newSuperType.upperIfFlexible())?.let { return it } + + // we should add constraints with flexible types, otherwise we never get flexible type as answer in constraint system + addSubtypeConstraint(newSubType, newSuperType)?.let { return it } + + return isSubtypeOfForSingleClassifierType(newSubType.lowerIfFlexible(), newSuperType.upperIfFlexible()) } fun transformToNewType(type: SimpleType): SimpleType { @@ -137,9 +142,7 @@ object NewKotlinTypeChecker : KotlinTypeChecker { } } - private fun TypeCheckerContext.isSubtypeOfForNewTypes(subType: SimpleType, superType: SimpleType): Boolean { - if (isSubtypeByExternalRule(subType, superType)) return true // todo: do not call this for T? <: String? - + private fun TypeCheckerContext.checkSubtypeForSpecialCases(subType: SimpleType, superType: SimpleType): Boolean? { if (subType.isError || superType.isError) { if (errorTypeEqualsToAnything) return true @@ -155,7 +158,7 @@ object NewKotlinTypeChecker : KotlinTypeChecker { return it.supertypes.all { isSubtypeOf(subType, it.unwrap()) } } - return isSubtypeOfForSingleClassifierType(subType, superType) + return null } private fun TypeCheckerContext.hasNothingSupertype(type: SimpleType) = // todo add tests diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/TypeCheckerContext.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/TypeCheckerContext.kt index 7da03ea34e1..2b310627ad3 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/TypeCheckerContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/TypeCheckerContext.kt @@ -28,7 +28,7 @@ open class TypeCheckerContext(val errorTypeEqualsToAnything: Boolean) { private var supertypesDeque: ArrayDeque? = null private var supertypesSet: MutableSet? = null - open fun isSubtypeByExternalRule(subType: SimpleType, superType: SimpleType) = false + open fun addSubtypeConstraint(subType: UnwrappedType, superType: UnwrappedType): Boolean? = null inline fun runWithArgumentsSettings(subArgument: UnwrappedType, f: TypeCheckerContext.() -> T): T { if (argumentsDepth > 100) {