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:
Victor Petukhov
2021-04-27 14:05:35 +03:00
parent 5d0461c722
commit ac7b459f2a
49 changed files with 1536 additions and 75 deletions
@@ -288,7 +288,11 @@ internal class DescriptorRendererImpl(
override fun renderTypeConstructor(typeConstructor: TypeConstructor): String = when (val cd = typeConstructor.declarationDescriptor) {
is TypeParameterDescriptor, is ClassDescriptor, is TypeAliasDescriptor -> renderClassifierName(cd)
null -> typeConstructor.toString()
null -> {
if (typeConstructor is IntersectionTypeConstructor) {
typeConstructor.makeDebugNameForIntersectionType { if (it is StubType) it.originalTypeVariable else it }
} else typeConstructor.toString()
}
else -> error("Unexpected classifier: " + cd::class.java)
}
@@ -61,11 +61,12 @@ class IntersectionTypeConstructor(typesToIntersect: Collection<KotlinType>) : Ty
override fun getBuiltIns(): KotlinBuiltIns =
intersectedTypes.iterator().next().constructor.builtIns
override fun toString(): String =
makeDebugNameForIntersectionType(intersectedTypes)
override fun toString(): String = makeDebugNameForIntersectionType()
private fun makeDebugNameForIntersectionType(resultingTypes: Iterable<KotlinType>): String =
resultingTypes.sortedBy { it.toString() }.joinToString(separator = " & ", prefix = "{", postfix = "}")
fun makeDebugNameForIntersectionType(getProperTypeRelatedToStringify: (KotlinType) -> Any = { it.toString() }): String {
return intersectedTypes.sortedBy { getProperTypeRelatedToStringify(it).toString() }
.joinToString(separator = " & ", prefix = "{", postfix = "}") { getProperTypeRelatedToStringify(it).toString() }
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
@@ -23,6 +23,17 @@ class StubType(
}
}
class StubTypeForTypeVariablesInSubtyping(
originalTypeVariable: TypeConstructor,
isMarkedNullable: Boolean,
constructor: TypeConstructor = ErrorUtils.createErrorTypeConstructor("Constructor for non fixed type: $originalTypeVariable"),
memberScope: MemberScope = ErrorUtils.createErrorScope("Scope for non fixed type: $originalTypeVariable")
) : AbstractStubType(originalTypeVariable, isMarkedNullable, constructor, memberScope), StubTypeMarker {
override fun materialize(newNullability: Boolean): AbstractStubType {
return StubTypeForTypeVariablesInSubtyping(originalTypeVariable, newNullability, constructor, memberScope)
}
}
// This type is used as a replacement of type variables for provideDelegate resolve
class StubTypeForProvideDelegateReceiver(
originalTypeVariable: TypeConstructor,
@@ -54,7 +65,7 @@ abstract class AbstractStubType(
}
override fun toString(): String {
return "NonFixed: $originalTypeVariable"
return "NonFixed: $originalTypeVariable${if (isMarkedNullable) "?" else ""}"
}
@TypeRefinement
@@ -81,7 +81,12 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
override fun SimpleTypeMarker.isStubType(): Boolean {
require(this is SimpleType, this::errorMessage)
return this is AbstractStubType
return this is StubType || this is StubTypeForProvideDelegateReceiver
}
override fun SimpleTypeMarker.isStubTypeForVariableInSubtyping(): Boolean {
require(this is SimpleType, this::errorMessage)
return this is StubTypeForTypeVariablesInSubtyping
}
override fun CapturedTypeMarker.lowerType(): KotlinTypeMarker? {
@@ -543,6 +548,10 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
errorSupportedOnlyInTypeInference()
}
override fun createStubTypeForTypeVariablesInSubtyping(typeVariable: TypeVariableMarker): StubTypeMarker {
errorSupportedOnlyInTypeInference()
}
override fun KotlinTypeMarker.isSpecial(): Boolean {
require(this is KotlinType)
return this is TypeUtils.SpecialType
@@ -136,6 +136,8 @@ class FlexibleTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : Flexibl
return renderer.renderFlexibleType(renderer.renderType(lowerBound), renderer.renderType(upperBound), builtIns)
}
override fun toString() = "($lowerBound..$upperBound)"
override fun makeNullableAsSpecified(newNullability: Boolean): UnwrappedType = KotlinTypeFactory.flexibleType(
lowerBound.makeNullableAsSpecified(newNullability),
upperBound.makeNullableAsSpecified(newNullability)