From 9fa3bce73ab5270a5a6c4551cb669c6c249a7e36 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 7 Jun 2017 15:11:04 +0300 Subject: [PATCH] [NI] Fix special case of captured type handling in subtyping Given the subtyping constraint X <: CapturedType(in Y) we should check only X <: Y if X contains type variables. --- .../TypeCheckerContextForConstraintSystem.kt | 4 ++-- .../kotlin/types/checker/NewKotlinTypeChecker.kt | 14 ++++++++------ .../kotlin/types/checker/TypeCheckerContext.kt | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerContextForConstraintSystem.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerContextForConstraintSystem.kt index 0dc9d681894..239bb8086de 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerContextForConstraintSystem.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerContextForConstraintSystem.kt @@ -29,8 +29,8 @@ abstract class TypeCheckerContextForConstraintSystem : TypeCheckerContext(errorT abstract fun addUpperConstraint(typeVariable: TypeConstructor, superType: UnwrappedType) abstract fun addLowerConstraint(typeVariable: TypeConstructor, subType: UnwrappedType) - override fun allowSubtypeViaLowerTypeForCapturedType(subType: SimpleType, superType: NewCapturedType) = - !subType.contains { it.anyBound(this::isMyTypeVariable) } + override fun shouldCheckOnlyLowerBoundForCapturedType(subType: SimpleType, superType: NewCapturedType) = + subType.contains { it.anyBound(this::isMyTypeVariable) } /** * todo: possible we should override this method, because otherwise OR in subtyping transformed to AND in constraint system 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 6cb99eee802..257763f1d52 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewKotlinTypeChecker.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewKotlinTypeChecker.kt @@ -159,12 +159,14 @@ object NewKotlinTypeChecker : KotlinTypeChecker { return StrictEqualityTypeChecker.strictEqualTypes(subType.makeNullableAsSpecified(false), superType.makeNullableAsSpecified(false)) } - if (superType is NewCapturedType && - superType.lowerType != null && - allowSubtypeViaLowerTypeForCapturedType(subType, superType) && - isSubtypeOf(subType, superType.lowerType)) - { - return true + if (superType is NewCapturedType && superType.lowerType != null) { + val subtypeOfLowerType = isSubtypeOf(subType, superType.lowerType) + if (shouldCheckOnlyLowerBoundForCapturedType(subType, superType)) { + return subtypeOfLowerType + } + else if (subtypeOfLowerType) { + return true + } } (superType.constructor as? IntersectionTypeConstructor)?.let { 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 ba0a6683bc3..4d6b239becd 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/TypeCheckerContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/TypeCheckerContext.kt @@ -33,7 +33,7 @@ open class TypeCheckerContext(val errorTypeEqualsToAnything: Boolean, val allowe return a == b } - open fun allowSubtypeViaLowerTypeForCapturedType(subType: SimpleType, superType: NewCapturedType): Boolean = true + open fun shouldCheckOnlyLowerBoundForCapturedType(subType: SimpleType, superType: NewCapturedType): Boolean = false open val sameConstructorPolicy get() = SeveralSupertypesWithSameConstructorPolicy.INTERSECT_ARGUMENTS_AND_CHECK_AGAIN internal inline fun runWithArgumentsSettings(subArgument: UnwrappedType, f: TypeCheckerContext.() -> T): T {