Support type inference for self type materialization calls

This commit is contained in:
Victor Petukhov
2021-06-30 16:21:58 +03:00
parent 44cf4be1e5
commit 51c5a54e31
21 changed files with 183 additions and 89 deletions
@@ -528,7 +528,9 @@ object AbstractTypeChecker {
* so if CapturedType(out Bar) is the same as a type of Foo's argument and Foo is a self type, then subtyping should return true.
* If we don't handle this case separately, subtyping may not converge due to the nature of the capturing.
*/
if (subType is CapturedTypeMarker) {
val subTypeConstructor = subType.typeConstructor()
if (subType is CapturedTypeMarker
|| (subTypeConstructor.isIntersection() && subTypeConstructor.supertypes().all { it is CapturedTypeMarker })) {
val typeParameter =
context.typeSystemContext.getTypeParameterForArgumentInBaseIfItEqualToTarget(baseType = superType, targetType = subType)
if (typeParameter != null && typeParameter.hasRecursiveBounds(superType.typeConstructor())) {
@@ -30,7 +30,6 @@ interface TypeSystemCommonBackendContext : TypeSystemContext {
*/
fun KotlinTypeMarker.getAnnotationFirstArgumentValue(fqName: FqName): Any?
fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker?
fun TypeConstructorMarker.isInlineClass(): Boolean
fun TypeConstructorMarker.isInnerClass(): Boolean
fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker
@@ -175,6 +175,7 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
fun KotlinTypeMarker.removeExactAnnotation(): KotlinTypeMarker
fun SimpleTypeMarker.replaceArguments(newArguments: List<TypeArgumentMarker>): SimpleTypeMarker
fun SimpleTypeMarker.replaceArguments(replacement: (TypeArgumentMarker) -> TypeArgumentMarker): SimpleTypeMarker
fun KotlinTypeMarker.hasExactAnnotation(): Boolean
fun KotlinTypeMarker.hasNoInferAnnotation(): Boolean
@@ -248,6 +249,22 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
* In future once we have only FIR (or FE 1.0 behavior is fixed) this method should be inlined to the use-site
*/
fun SimpleTypeMarker.createConstraintPartForLowerBoundAndFlexibleTypeVariable(): KotlinTypeMarker
fun createCapturedStarProjectionForSelfType(
typeVariable: TypeVariableTypeConstructorMarker,
selfType: SimpleTypeMarker,
): SimpleTypeMarker? {
val typeParameter = typeVariable.typeParameter ?: return null
val starProjection = createStarProjection(typeParameter)
val superType = selfType.replaceArguments {
val constructor = it.getType().typeConstructor()
if (constructor is TypeVariableTypeConstructorMarker && constructor == typeVariable) {
starProjection
} else it
}
return createCapturedType(starProjection, listOf(superType), lowerType = null, CaptureStatus.FROM_EXPRESSION)
}
}
@@ -313,12 +330,14 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
fun TypeConstructorMarker.parametersCount(): Int
fun TypeConstructorMarker.getParameter(index: Int): TypeParameterMarker
fun TypeConstructorMarker.getParameters(): List<TypeParameterMarker>
fun TypeConstructorMarker.supertypes(): Collection<KotlinTypeMarker>
fun TypeConstructorMarker.isIntersection(): Boolean
fun TypeConstructorMarker.isClassTypeConstructor(): Boolean
fun TypeConstructorMarker.isInterface(): Boolean
fun TypeConstructorMarker.isIntegerLiteralTypeConstructor(): Boolean
fun TypeConstructorMarker.isLocalType(): Boolean
fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker?
val TypeVariableTypeConstructorMarker.typeParameter: TypeParameterMarker?
@@ -327,7 +346,7 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
fun TypeParameterMarker.getUpperBound(index: Int): KotlinTypeMarker
fun TypeParameterMarker.getUpperBounds(): List<KotlinTypeMarker>
fun TypeParameterMarker.getTypeConstructor(): TypeConstructorMarker
fun TypeParameterMarker.hasRecursiveBounds(selfConstructor: TypeConstructorMarker): Boolean
fun TypeParameterMarker.hasRecursiveBounds(selfConstructor: TypeConstructorMarker? = null): Boolean
fun areEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean