From eadd1355c2e474a10f5b51ee0f2cf9b3a10a659e Mon Sep 17 00:00:00 2001 From: Dmitry Savvinov Date: Wed, 22 Nov 2017 19:25:40 +0300 Subject: [PATCH] [NI] Add ErrorType constraint Previously, constraint wasn't added if bound was ErrorType. That could cause TypeVariable to be inferred to Any?/Nothing instead of ErrorType, which could influence other parts of analysis (in particular, inferring Nothing instead of ErrorType can cause bogus UNREACHABLE_CODE diagnostics) Because of that fix, intersection type can be added to CS as supertype, which provokes AssertionError. This commit also relaxes this assertion, as it seems that it's valid that supertype is an intersection type. --- .../components/TypeCheckerContextForConstraintSystem.kt | 4 ++-- .../jetbrains/kotlin/types/checker/NewKotlinTypeChecker.kt | 5 ++++- 2 files changed, 6 insertions(+), 3 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 4c2a39f80a8..7fae9e1f315 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 @@ -225,8 +225,8 @@ abstract class TypeCheckerContextForConstraintSystem : TypeCheckerContext(errorT with(NewKotlinTypeChecker) { this@TypeCheckerContextForConstraintSystem.isSubtypeOf(subType, superType) } private fun assertInputTypes(subType: UnwrappedType, superType: UnwrappedType) { - fun correctSubType(subType: SimpleType) = subType.isSingleClassifierType || subType.isIntersectionType || isMyTypeVariable(subType) - fun correctSuperType(superType: SimpleType) = superType.isSingleClassifierType || isMyTypeVariable(superType) + fun correctSubType(subType: SimpleType) = subType.isSingleClassifierType || subType.isIntersectionType || isMyTypeVariable(subType) || subType.isError + fun correctSuperType(superType: SimpleType) = superType.isSingleClassifierType || superType.isIntersectionType || isMyTypeVariable(superType) || superType.isError assert(subType.bothBounds(::correctSubType)) { "Not singleClassifierType and not intersection subType: $subType" 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 60859d5d4d9..0ca16a093bb 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewKotlinTypeChecker.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewKotlinTypeChecker.kt @@ -121,7 +121,10 @@ object NewKotlinTypeChecker : KotlinTypeChecker { val newSubType = transformToNewType(subType) val newSuperType = transformToNewType(superType) - checkSubtypeForSpecialCases(newSubType.lowerIfFlexible(), newSuperType.upperIfFlexible())?.let { return it } + checkSubtypeForSpecialCases(newSubType.lowerIfFlexible(), newSuperType.upperIfFlexible())?.let { + addSubtypeConstraint(newSubType, newSuperType) + 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 }