[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.
This commit is contained in:
Dmitry Savvinov
2017-11-22 19:25:40 +03:00
parent 8e50a58408
commit eadd1355c2
2 changed files with 6 additions and 3 deletions
@@ -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"
@@ -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 }