Do subtyping with stub types properly
1) Return stub type if we are calculating super type between two same stub types 2) Return nullable Any if those stub types are different
This commit is contained in:
+29
-10
@@ -59,7 +59,7 @@ object NewCommonSuperTypeCalculator {
|
||||
|
||||
if (!isTopLevelType) {
|
||||
val nonStubTypes =
|
||||
types.filter { !isStubRelatedType(it.lowerBoundIfFlexible()) && !isStubRelatedType(it.upperBoundIfFlexible()) }
|
||||
types.filter { !isTypeVariable(it.lowerBoundIfFlexible()) && !isTypeVariable(it.upperBoundIfFlexible()) }
|
||||
val equalToEachOtherTypes = nonStubTypes.filter { potentialCommonSuperType ->
|
||||
nonStubTypes.all {
|
||||
AbstractTypeChecker.equalTypes(this, it, potentialCommonSuperType)
|
||||
@@ -87,7 +87,7 @@ object NewCommonSuperTypeCalculator {
|
||||
|
||||
// i.e. result type also should be marked nullable
|
||||
val notAllNotNull =
|
||||
types.any { !isStubRelatedType(it) && !AbstractNullabilityChecker.isSubtypeOfAny(contextStubTypesEqualToAnything, it) }
|
||||
types.any { !isTypeVariable(it) && !AbstractNullabilityChecker.isSubtypeOfAny(contextStubTypesEqualToAnything, it) }
|
||||
val notNullTypes = if (notAllNotNull) types.map { it.withNullability(false) } else types
|
||||
|
||||
val commonSuperType = commonSuperTypeForNotNullTypes(notNullTypes, depth, contextStubTypesEqualToAnything, contextStubTypesNotEqual)
|
||||
@@ -164,14 +164,23 @@ object NewCommonSuperTypeCalculator {
|
||||
): SimpleTypeMarker {
|
||||
if (types.size == 1) return types.single()
|
||||
|
||||
val nonStubTypes = types.filter { !isStubRelatedType(it) }
|
||||
if (nonStubTypes.size == 1) return nonStubTypes.single()
|
||||
val nonTypeVariables = types.filter { !isTypeVariable(it) }
|
||||
if (nonTypeVariables.size == 1) return nonTypeVariables.single()
|
||||
|
||||
assert(nonStubTypes.isNotEmpty()) {
|
||||
assert(nonTypeVariables.isNotEmpty()) {
|
||||
"There should be at least one non-stub type to compute common supertype but there are: $types"
|
||||
}
|
||||
|
||||
val uniqueTypes = uniquify(nonStubTypes, contextStubTypesNotEqual)
|
||||
val stubTypeVariables = types.filter { isStubTypeVariable(it) }
|
||||
val nonStubTypeVariables = types.filter { !isStubTypeVariable(it) }
|
||||
val areAllNonStubTypesNothing = nonStubTypeVariables.isNotEmpty() && nonStubTypeVariables.all { it.isNothing() }
|
||||
if (nonStubTypeVariables.size == 1 && !areAllNonStubTypesNothing) return nonStubTypeVariables.single()
|
||||
|
||||
if (nonStubTypeVariables.isEmpty() || areAllNonStubTypesNothing) {
|
||||
return uniquify(stubTypeVariables, contextStubTypesNotEqual).singleOrNull() ?: nullableAnyType()
|
||||
}
|
||||
|
||||
val uniqueTypes = uniquify(nonTypeVariables, contextStubTypesNotEqual)
|
||||
if (uniqueTypes.size == 1) return uniqueTypes.single()
|
||||
|
||||
val explicitSupertypes = filterSupertypes(uniqueTypes, contextStubTypesNotEqual)
|
||||
@@ -183,16 +192,26 @@ object NewCommonSuperTypeCalculator {
|
||||
return findSuperTypeConstructorsAndIntersectResult(explicitSupertypes, depth, contextStubTypesEqualToAnything)
|
||||
}
|
||||
|
||||
private fun TypeSystemCommonSuperTypesContext.isStubRelatedType(type: SimpleTypeMarker): Boolean {
|
||||
return type.isStubType() || isCapturedStubType(type)
|
||||
private fun TypeSystemCommonSuperTypesContext.isStubTypeVariable(type: SimpleTypeMarker): Boolean {
|
||||
return type.isStubType() || isStubCapturedTypeVariable(type)
|
||||
}
|
||||
|
||||
private fun TypeSystemCommonSuperTypesContext.isCapturedStubType(type: SimpleTypeMarker): Boolean {
|
||||
private fun TypeSystemCommonSuperTypesContext.isStubCapturedTypeVariable(type: SimpleTypeMarker): Boolean {
|
||||
val projectedType =
|
||||
type.asCapturedType()?.typeConstructor()?.projection()?.takeUnless { it.isStarProjection() }?.getType() ?: return false
|
||||
return projectedType.asSimpleType()?.isStubType() == true
|
||||
}
|
||||
|
||||
private fun TypeSystemCommonSuperTypesContext.isTypeVariable(type: SimpleTypeMarker): Boolean {
|
||||
return type.isStubTypeForVariableInSubtyping() || isCapturedTypeVariable(type)
|
||||
}
|
||||
|
||||
private fun TypeSystemCommonSuperTypesContext.isCapturedTypeVariable(type: SimpleTypeMarker): Boolean {
|
||||
val projectedType =
|
||||
type.asCapturedType()?.typeConstructor()?.projection()?.takeUnless { it.isStarProjection() }?.getType() ?: return false
|
||||
return projectedType.asSimpleType()?.isStubTypeForVariableInSubtyping() == true
|
||||
}
|
||||
|
||||
private fun TypeSystemCommonSuperTypesContext.findErrorTypeInSupertypes(
|
||||
types: List<SimpleTypeMarker>,
|
||||
contextStubTypesEqualToAnything: AbstractTypeCheckerContext
|
||||
@@ -288,7 +307,7 @@ object NewCommonSuperTypeCalculator {
|
||||
null
|
||||
}
|
||||
|
||||
typeArgument.getType().lowerBoundIfFlexible().isStubType() -> null
|
||||
typeArgument.getType().lowerBoundIfFlexible().isStubTypeForVariableInSubtyping() -> null
|
||||
|
||||
else -> typeArgument
|
||||
}
|
||||
|
||||
+1
-1
@@ -43,6 +43,6 @@ fun ConstraintStorage.buildNotFixedVariablesToNonSubtypableTypesSubstitutor(
|
||||
context: TypeSystemInferenceExtensionContext
|
||||
): TypeSubstitutorMarker {
|
||||
return context.typeSubstitutorByTypeConstructor(
|
||||
notFixedTypeVariables.mapValues { context.createStubType(it.value.typeVariable) }
|
||||
notFixedTypeVariables.mapValues { context.createStubTypeForTypeVariablesInSubtyping(it.value.typeVariable) }
|
||||
)
|
||||
}
|
||||
|
||||
+2
-4
@@ -134,15 +134,13 @@ class ResultTypeResolver(
|
||||
val types = sinkIntegerLiteralTypes(lowerConstraintTypes)
|
||||
var commonSuperType = computeCommonSuperType(types)
|
||||
|
||||
if (commonSuperType.contains { it is StubTypeMarker }) {
|
||||
if (commonSuperType.contains { it.asSimpleType()?.isStubTypeForVariableInSubtyping() == true }) {
|
||||
val typesWithoutStubs = types.filter { lowerType ->
|
||||
!lowerType.contains { it is StubTypeMarker }
|
||||
!lowerType.contains { it.asSimpleType()?.isStubTypeForVariableInSubtyping() == true }
|
||||
}
|
||||
|
||||
if (typesWithoutStubs.isNotEmpty()) {
|
||||
commonSuperType = computeCommonSuperType(typesWithoutStubs)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user