[NI] Improve type inference for T vs Captured(in Smt)
If we has Inv<T> <: Inv<Captured(in Foo)> then we should get: - T <: Captured(in Foo) - Captured(in Foo) <: T Before this commit we got: T <: Foo instead first constraint.
This commit is contained in:
committed by
Mikhail Zarechenskiy
parent
91241a34d1
commit
915ac32bfb
+5
-2
@@ -29,8 +29,11 @@ abstract class TypeCheckerContextForConstraintSystem : TypeCheckerContext(errorT
|
||||
abstract fun addUpperConstraint(typeVariable: TypeConstructor, superType: UnwrappedType)
|
||||
abstract fun addLowerConstraint(typeVariable: TypeConstructor, subType: UnwrappedType)
|
||||
|
||||
override fun shouldCheckOnlyLowerBoundForCapturedType(subType: SimpleType, superType: NewCapturedType) =
|
||||
subType.contains { it.anyBound(this::isMyTypeVariable) }
|
||||
override fun getLowerCapturedTypePolicy(subType: SimpleType, superType: NewCapturedType) = when {
|
||||
isMyTypeVariable(subType) -> LowerCapturedTypePolicy.SKIP_LOWER
|
||||
subType.contains { it.anyBound(this::isMyTypeVariable) } -> LowerCapturedTypePolicy.CHECK_ONLY_LOWER
|
||||
else -> LowerCapturedTypePolicy.CHECK_SUBTYPE_AND_LOWER
|
||||
}
|
||||
|
||||
/**
|
||||
* todo: possible we should override this method, because otherwise OR in subtyping transformed to AND in constraint system
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructor
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.TypeCheckerContext.LowerCapturedTypePolicy.*
|
||||
import org.jetbrains.kotlin.types.checker.TypeCheckerContext.SeveralSupertypesWithSameConstructorPolicy.*
|
||||
import org.jetbrains.kotlin.types.checker.TypeCheckerContext.SupertypesPolicy
|
||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||
@@ -160,12 +161,10 @@ object NewKotlinTypeChecker : KotlinTypeChecker {
|
||||
}
|
||||
|
||||
if (superType is NewCapturedType && superType.lowerType != null) {
|
||||
val subtypeOfLowerType = isSubtypeOf(subType, superType.lowerType)
|
||||
if (shouldCheckOnlyLowerBoundForCapturedType(subType, superType)) {
|
||||
return subtypeOfLowerType
|
||||
}
|
||||
else if (subtypeOfLowerType) {
|
||||
return true
|
||||
when (getLowerCapturedTypePolicy(subType, superType)) {
|
||||
CHECK_ONLY_LOWER -> return isSubtypeOf(subType, superType.lowerType)
|
||||
CHECK_SUBTYPE_AND_LOWER -> if(isSubtypeOf(subType, superType.lowerType)) return true
|
||||
SKIP_LOWER -> { /*do nothing*/ }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ open class TypeCheckerContext(val errorTypeEqualsToAnything: Boolean, val allowe
|
||||
return a == b
|
||||
}
|
||||
|
||||
open fun shouldCheckOnlyLowerBoundForCapturedType(subType: SimpleType, superType: NewCapturedType): Boolean = false
|
||||
open fun getLowerCapturedTypePolicy(subType: SimpleType, superType: NewCapturedType) = LowerCapturedTypePolicy.CHECK_SUBTYPE_AND_LOWER
|
||||
open val sameConstructorPolicy get() = SeveralSupertypesWithSameConstructorPolicy.INTERSECT_ARGUMENTS_AND_CHECK_AGAIN
|
||||
|
||||
internal inline fun <T> runWithArgumentsSettings(subArgument: UnwrappedType, f: TypeCheckerContext.() -> T): T {
|
||||
@@ -127,5 +127,11 @@ open class TypeCheckerContext(val errorTypeEqualsToAnything: Boolean, val allowe
|
||||
INTERSECT_ARGUMENTS_AND_CHECK_AGAIN
|
||||
}
|
||||
|
||||
enum class LowerCapturedTypePolicy {
|
||||
CHECK_ONLY_LOWER,
|
||||
CHECK_SUBTYPE_AND_LOWER,
|
||||
SKIP_LOWER
|
||||
}
|
||||
|
||||
val UnwrappedType.isAllowedTypeVariable: Boolean get() = allowedTypeVariable && constructor is NewTypeVariableConstructor
|
||||
}
|
||||
Reference in New Issue
Block a user