NI: propagate isNullabilityConstraint flag into constraint injector and inherit it
^KT-37510 Fixed
This commit is contained in:
+18
@@ -2167,6 +2167,24 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt32249.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt32249.kt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/nothingType")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NothingType extends AbstractFirOldFrontendDiagnosticsTestWithStdlib {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNothingType() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/inference/nothingType"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("dontInferToNullableNothingInDelegates.kt")
|
||||||
|
public void testDontInferToNullableNothingInDelegates() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/nothingType/dontInferToNullableNothingInDelegates.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inline")
|
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inline")
|
||||||
|
|||||||
+1
-1
@@ -259,7 +259,7 @@ class CoroutineInferenceSupport(
|
|||||||
private val allowOnlyTrivialConstraints: Boolean
|
private val allowOnlyTrivialConstraints: Boolean
|
||||||
) : ClassicTypeCheckerContext(errorTypeEqualsToAnything = true) {
|
) : ClassicTypeCheckerContext(errorTypeEqualsToAnything = true) {
|
||||||
|
|
||||||
override fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean? {
|
override fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker, isFromNullabilityConstraint: Boolean): Boolean? {
|
||||||
require(subType is UnwrappedType)
|
require(subType is UnwrappedType)
|
||||||
require(superType is UnwrappedType)
|
require(superType is UnwrappedType)
|
||||||
val typeTemplate = subType as? TypeTemplate ?: superType as? TypeTemplate
|
val typeTemplate = subType as? TypeTemplate ?: superType as? TypeTemplate
|
||||||
|
|||||||
+24
-8
@@ -28,7 +28,11 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck
|
|||||||
// super and sub type isSingleClassifierType
|
// super and sub type isSingleClassifierType
|
||||||
abstract fun addUpperConstraint(typeVariable: TypeConstructorMarker, superType: KotlinTypeMarker)
|
abstract fun addUpperConstraint(typeVariable: TypeConstructorMarker, superType: KotlinTypeMarker)
|
||||||
|
|
||||||
abstract fun addLowerConstraint(typeVariable: TypeConstructorMarker, subType: KotlinTypeMarker)
|
abstract fun addLowerConstraint(
|
||||||
|
typeVariable: TypeConstructorMarker,
|
||||||
|
subType: KotlinTypeMarker,
|
||||||
|
isFromNullabilityConstraint: Boolean = false
|
||||||
|
)
|
||||||
|
|
||||||
override fun getLowerCapturedTypePolicy(subType: SimpleTypeMarker, superType: CapturedTypeMarker): LowerCapturedTypePolicy {
|
override fun getLowerCapturedTypePolicy(subType: SimpleTypeMarker, superType: CapturedTypeMarker): LowerCapturedTypePolicy {
|
||||||
return when {
|
return when {
|
||||||
@@ -52,7 +56,11 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck
|
|||||||
* then we can get wrong result.
|
* then we can get wrong result.
|
||||||
* override val sameConstructorPolicy get() = SeveralSupertypesWithSameConstructorPolicy.TAKE_FIRST_FOR_SUBTYPING
|
* override val sameConstructorPolicy get() = SeveralSupertypesWithSameConstructorPolicy.TAKE_FIRST_FOR_SUBTYPING
|
||||||
*/
|
*/
|
||||||
final override fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean? {
|
final override fun addSubtypeConstraint(
|
||||||
|
subType: KotlinTypeMarker,
|
||||||
|
superType: KotlinTypeMarker,
|
||||||
|
isFromNullabilityConstraint: Boolean
|
||||||
|
): Boolean? {
|
||||||
val hasNoInfer = subType.isTypeVariableWithNoInfer() || superType.isTypeVariableWithNoInfer()
|
val hasNoInfer = subType.isTypeVariableWithNoInfer() || superType.isTypeVariableWithNoInfer()
|
||||||
if (hasNoInfer) return true
|
if (hasNoInfer) return true
|
||||||
|
|
||||||
@@ -64,10 +72,10 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck
|
|||||||
val mySuperType =
|
val mySuperType =
|
||||||
if (hasExact) extractTypeForProjectedType(superType, out = false) ?: superType.removeExactAnnotation() else superType
|
if (hasExact) extractTypeForProjectedType(superType, out = false) ?: superType.removeExactAnnotation() else superType
|
||||||
|
|
||||||
val result = internalAddSubtypeConstraint(mySubType, mySuperType)
|
val result = internalAddSubtypeConstraint(mySubType, mySuperType, isFromNullabilityConstraint)
|
||||||
if (!hasExact) return result
|
if (!hasExact) return result
|
||||||
|
|
||||||
val result2 = internalAddSubtypeConstraint(mySuperType, mySubType)
|
val result2 = internalAddSubtypeConstraint(mySuperType, mySubType, isFromNullabilityConstraint)
|
||||||
|
|
||||||
if (result == null && result2 == null) return null
|
if (result == null && result2 == null) return null
|
||||||
return (result ?: true) && (result2 ?: true)
|
return (result ?: true) && (result2 ?: true)
|
||||||
@@ -93,13 +101,17 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck
|
|||||||
private fun KotlinTypeMarker.isTypeVariableWithNoInfer() =
|
private fun KotlinTypeMarker.isTypeVariableWithNoInfer() =
|
||||||
hasNoInferAnnotation() && anyBound(this@AbstractTypeCheckerContextForConstraintSystem::isMyTypeVariable)
|
hasNoInferAnnotation() && anyBound(this@AbstractTypeCheckerContextForConstraintSystem::isMyTypeVariable)
|
||||||
|
|
||||||
private fun internalAddSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean? {
|
private fun internalAddSubtypeConstraint(
|
||||||
|
subType: KotlinTypeMarker,
|
||||||
|
superType: KotlinTypeMarker,
|
||||||
|
isFromNullabilityConstraint: Boolean
|
||||||
|
): Boolean? {
|
||||||
assertInputTypes(subType, superType)
|
assertInputTypes(subType, superType)
|
||||||
|
|
||||||
var answer: Boolean? = null
|
var answer: Boolean? = null
|
||||||
|
|
||||||
if (superType.anyBound(this::isMyTypeVariable)) {
|
if (superType.anyBound(this::isMyTypeVariable)) {
|
||||||
answer = simplifyLowerConstraint(superType, subType)
|
answer = simplifyLowerConstraint(superType, subType, isFromNullabilityConstraint)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subType.anyBound(this::isMyTypeVariable)) {
|
if (subType.anyBound(this::isMyTypeVariable)) {
|
||||||
@@ -178,7 +190,11 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck
|
|||||||
*
|
*
|
||||||
* => (Foo..Bar) <: T! -- (Foo!! .. Bar) <: T
|
* => (Foo..Bar) <: T! -- (Foo!! .. Bar) <: T
|
||||||
*/
|
*/
|
||||||
private fun simplifyLowerConstraint(typeVariable: KotlinTypeMarker, subType: KotlinTypeMarker): Boolean {
|
private fun simplifyLowerConstraint(
|
||||||
|
typeVariable: KotlinTypeMarker,
|
||||||
|
subType: KotlinTypeMarker,
|
||||||
|
isFromNullabilityConstraint: Boolean = false
|
||||||
|
): Boolean {
|
||||||
val lowerConstraint = when (typeVariable) {
|
val lowerConstraint = when (typeVariable) {
|
||||||
is SimpleTypeMarker ->
|
is SimpleTypeMarker ->
|
||||||
/*
|
/*
|
||||||
@@ -229,7 +245,7 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck
|
|||||||
else -> error("sealed")
|
else -> error("sealed")
|
||||||
}
|
}
|
||||||
|
|
||||||
addLowerConstraint(typeVariable.typeConstructor(), lowerConstraint)
|
addLowerConstraint(typeVariable.typeConstructor(), lowerConstraint, isFromNullabilityConstraint)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-3
@@ -31,7 +31,8 @@ class ConstraintIncorporator(
|
|||||||
fun addNewIncorporatedConstraint(
|
fun addNewIncorporatedConstraint(
|
||||||
lowerType: KotlinTypeMarker,
|
lowerType: KotlinTypeMarker,
|
||||||
upperType: KotlinTypeMarker,
|
upperType: KotlinTypeMarker,
|
||||||
shouldTryUseDifferentFlexibilityForUpperType: Boolean
|
shouldTryUseDifferentFlexibilityForUpperType: Boolean,
|
||||||
|
isFromNullabilityConstraint: Boolean = false
|
||||||
)
|
)
|
||||||
|
|
||||||
fun addNewIncorporatedConstraint(typeVariable: TypeVariableMarker, type: KotlinTypeMarker, constraintContext: ConstraintContext)
|
fun addNewIncorporatedConstraint(typeVariable: TypeVariableMarker, type: KotlinTypeMarker, constraintContext: ConstraintContext)
|
||||||
@@ -62,7 +63,7 @@ class ConstraintIncorporator(
|
|||||||
if (constraint.kind != ConstraintKind.LOWER) {
|
if (constraint.kind != ConstraintKind.LOWER) {
|
||||||
getConstraintsForVariable(typeVariable).forEach {
|
getConstraintsForVariable(typeVariable).forEach {
|
||||||
if (it.kind != ConstraintKind.UPPER) {
|
if (it.kind != ConstraintKind.UPPER) {
|
||||||
addNewIncorporatedConstraint(it.type, constraint.type, shouldBeTypeVariableFlexible)
|
addNewIncorporatedConstraint(it.type, constraint.type, shouldBeTypeVariableFlexible, it.isNullabilityConstraint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,7 +232,10 @@ class ConstraintIncorporator(
|
|||||||
|
|
||||||
val inputTypePosition = baseConstraint.position.from.safeAs<OnlyInputTypeConstraintPosition>()
|
val inputTypePosition = baseConstraint.position.from.safeAs<OnlyInputTypeConstraintPosition>()
|
||||||
|
|
||||||
val isNullabilityConstraint = isUsefulForNullabilityConstraint && newConstraint.isNullableNothing()
|
val isNewConstraintUsefulForNullability = isUsefulForNullabilityConstraint && newConstraint.isNullableNothing()
|
||||||
|
val isOtherConstraintUsefulForNullability = otherConstraint.isNullabilityConstraint && otherConstraint.type.isNullableNothing()
|
||||||
|
val isNullabilityConstraint = isNewConstraintUsefulForNullability || isOtherConstraintUsefulForNullability
|
||||||
|
|
||||||
val constraintContext = ConstraintContext(kind, derivedFrom, inputTypePosition, isNullabilityConstraint)
|
val constraintContext = ConstraintContext(kind, derivedFrom, inputTypePosition, isNullabilityConstraint)
|
||||||
|
|
||||||
addNewIncorporatedConstraint(targetVariable, newConstraint, constraintContext)
|
addNewIncorporatedConstraint(targetVariable, newConstraint, constraintContext)
|
||||||
|
|||||||
+23
-8
@@ -181,13 +181,15 @@ class ConstraintInjector(
|
|||||||
fun runIsSubtypeOf(
|
fun runIsSubtypeOf(
|
||||||
lowerType: KotlinTypeMarker,
|
lowerType: KotlinTypeMarker,
|
||||||
upperType: KotlinTypeMarker,
|
upperType: KotlinTypeMarker,
|
||||||
shouldTryUseDifferentFlexibilityForUpperType: Boolean = false
|
shouldTryUseDifferentFlexibilityForUpperType: Boolean = false,
|
||||||
|
isFromNullabilityConstraint: Boolean = false
|
||||||
) {
|
) {
|
||||||
fun isSubtypeOf(upperType: KotlinTypeMarker) =
|
fun isSubtypeOf(upperType: KotlinTypeMarker) =
|
||||||
AbstractTypeChecker.isSubtypeOf(
|
AbstractTypeChecker.isSubtypeOf(
|
||||||
this@TypeCheckerContext as AbstractTypeCheckerContext,
|
this@TypeCheckerContext as AbstractTypeCheckerContext,
|
||||||
lowerType,
|
lowerType,
|
||||||
upperType
|
upperType,
|
||||||
|
isFromNullabilityConstraint
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!isSubtypeOf(upperType)) {
|
if (!isSubtypeOf(upperType)) {
|
||||||
@@ -215,8 +217,11 @@ class ConstraintInjector(
|
|||||||
override fun addUpperConstraint(typeVariable: TypeConstructorMarker, superType: KotlinTypeMarker) =
|
override fun addUpperConstraint(typeVariable: TypeConstructorMarker, superType: KotlinTypeMarker) =
|
||||||
addConstraint(typeVariable, superType, UPPER)
|
addConstraint(typeVariable, superType, UPPER)
|
||||||
|
|
||||||
override fun addLowerConstraint(typeVariable: TypeConstructorMarker, subType: KotlinTypeMarker) =
|
override fun addLowerConstraint(
|
||||||
addConstraint(typeVariable, subType, LOWER)
|
typeVariable: TypeConstructorMarker,
|
||||||
|
subType: KotlinTypeMarker,
|
||||||
|
isFromNullabilityConstraint: Boolean
|
||||||
|
) = addConstraint(typeVariable, subType, LOWER, isFromNullabilityConstraint)
|
||||||
|
|
||||||
private fun isCapturedTypeFromSubtyping(type: KotlinTypeMarker) =
|
private fun isCapturedTypeFromSubtyping(type: KotlinTypeMarker) =
|
||||||
when ((type as? CapturedTypeMarker)?.captureStatus()) {
|
when ((type as? CapturedTypeMarker)?.captureStatus()) {
|
||||||
@@ -226,22 +231,32 @@ class ConstraintInjector(
|
|||||||
error("Captured type for incorporation shouldn't escape from incorporation: $type\n" + renderBaseConstraint())
|
error("Captured type for incorporation shouldn't escape from incorporation: $type\n" + renderBaseConstraint())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addConstraint(typeVariableConstructor: TypeConstructorMarker, type: KotlinTypeMarker, kind: ConstraintKind) {
|
private fun addConstraint(
|
||||||
|
typeVariableConstructor: TypeConstructorMarker,
|
||||||
|
type: KotlinTypeMarker,
|
||||||
|
kind: ConstraintKind,
|
||||||
|
isFromNullabilityConstraint: Boolean = false
|
||||||
|
) {
|
||||||
val typeVariable = c.allTypeVariables[typeVariableConstructor]
|
val typeVariable = c.allTypeVariables[typeVariableConstructor]
|
||||||
?: error("Should by type variableConstructor: $typeVariableConstructor. ${c.allTypeVariables.values}")
|
?: error("Should by type variableConstructor: $typeVariableConstructor. ${c.allTypeVariables.values}")
|
||||||
|
|
||||||
addNewIncorporatedConstraint(typeVariable, type, ConstraintContext(kind, emptySet(), isNullabilityConstraint = false))
|
addNewIncorporatedConstraint(
|
||||||
|
typeVariable,
|
||||||
|
type,
|
||||||
|
ConstraintContext(kind, emptySet(), isNullabilityConstraint = isFromNullabilityConstraint)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// from ConstraintIncorporator.Context
|
// from ConstraintIncorporator.Context
|
||||||
override fun addNewIncorporatedConstraint(
|
override fun addNewIncorporatedConstraint(
|
||||||
lowerType: KotlinTypeMarker,
|
lowerType: KotlinTypeMarker,
|
||||||
upperType: KotlinTypeMarker,
|
upperType: KotlinTypeMarker,
|
||||||
shouldTryUseDifferentFlexibilityForUpperType: Boolean
|
shouldTryUseDifferentFlexibilityForUpperType: Boolean,
|
||||||
|
isFromNullabilityConstraint: Boolean
|
||||||
) {
|
) {
|
||||||
if (lowerType === upperType) return
|
if (lowerType === upperType) return
|
||||||
if (c.isAllowedType(lowerType) && c.isAllowedType(upperType)) {
|
if (c.isAllowedType(lowerType) && c.isAllowedType(upperType)) {
|
||||||
runIsSubtypeOf(lowerType, upperType, shouldTryUseDifferentFlexibilityForUpperType)
|
runIsSubtypeOf(lowerType, upperType, shouldTryUseDifferentFlexibilityForUpperType, isFromNullabilityConstraint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun <K> materialize(): K? { return null }
|
||||||
|
|
||||||
|
val x: String? by lazy { materialize() }
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun <K> materialize(): K? { return null }
|
||||||
|
|
||||||
|
val x: String? by lazy { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String?")!>materialize()<!> }
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public val x: kotlin.String?
|
||||||
|
public fun </*0*/ K> materialize(): K?
|
||||||
+18
@@ -3182,6 +3182,24 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt32249.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt32249.kt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/nothingType")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NothingType extends AbstractDiagnosticsTestWithStdLib {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNothingType() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/inference/nothingType"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("dontInferToNullableNothingInDelegates.kt")
|
||||||
|
public void testDontInferToNullableNothingInDelegates() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/nothingType/dontInferToNullableNothingInDelegates.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inline")
|
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inline")
|
||||||
|
|||||||
compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
Generated
+18
@@ -3182,6 +3182,24 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt32249.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt32249.kt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/nothingType")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NothingType extends AbstractDiagnosticsTestWithStdLibUsingJavac {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNothingType() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/inference/nothingType"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("dontInferToNullableNothingInDelegates.kt")
|
||||||
|
public void testDontInferToNullableNothingInDelegates() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/nothingType/dontInferToNullableNothingInDelegates.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inline")
|
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inline")
|
||||||
|
|||||||
@@ -47,7 +47,12 @@ abstract class AbstractTypeCheckerContext : TypeSystemContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open fun getLowerCapturedTypePolicy(subType: SimpleTypeMarker, superType: CapturedTypeMarker): LowerCapturedTypePolicy = CHECK_SUBTYPE_AND_LOWER
|
open fun getLowerCapturedTypePolicy(subType: SimpleTypeMarker, superType: CapturedTypeMarker): LowerCapturedTypePolicy = CHECK_SUBTYPE_AND_LOWER
|
||||||
open fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean? = null
|
|
||||||
|
open fun addSubtypeConstraint(
|
||||||
|
subType: KotlinTypeMarker,
|
||||||
|
superType: KotlinTypeMarker,
|
||||||
|
isFromNullabilityConstraint: Boolean = false
|
||||||
|
): Boolean? = null
|
||||||
|
|
||||||
enum class LowerCapturedTypePolicy {
|
enum class LowerCapturedTypePolicy {
|
||||||
CHECK_ONLY_LOWER,
|
CHECK_ONLY_LOWER,
|
||||||
@@ -162,9 +167,17 @@ object AbstractTypeChecker {
|
|||||||
return AbstractTypeChecker.equalTypes(context.newBaseTypeCheckerContext(false, stubTypesEqualToAnything), a, b)
|
return AbstractTypeChecker.equalTypes(context.newBaseTypeCheckerContext(false, stubTypesEqualToAnything), a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isSubtypeOf(context: AbstractTypeCheckerContext, subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean {
|
fun isSubtypeOf(
|
||||||
|
context: AbstractTypeCheckerContext,
|
||||||
|
subType: KotlinTypeMarker,
|
||||||
|
superType: KotlinTypeMarker,
|
||||||
|
isFromNullabilityConstraint: Boolean = false
|
||||||
|
): Boolean {
|
||||||
if (subType === superType) return true
|
if (subType === superType) return true
|
||||||
return with(context) { completeIsSubTypeOf(prepareType(refineType(subType)), prepareType(refineType(superType))) }
|
|
||||||
|
return with(context) {
|
||||||
|
completeIsSubTypeOf(prepareType(refineType(subType)), prepareType(refineType(superType)), isFromNullabilityConstraint)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun equalTypes(context: AbstractTypeCheckerContext, a: KotlinTypeMarker, b: KotlinTypeMarker): Boolean = with(context) {
|
fun equalTypes(context: AbstractTypeCheckerContext, a: KotlinTypeMarker, b: KotlinTypeMarker): Boolean = with(context) {
|
||||||
@@ -186,14 +199,18 @@ object AbstractTypeChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun AbstractTypeCheckerContext.completeIsSubTypeOf(subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean {
|
private fun AbstractTypeCheckerContext.completeIsSubTypeOf(
|
||||||
|
subType: KotlinTypeMarker,
|
||||||
|
superType: KotlinTypeMarker,
|
||||||
|
isFromNullabilityConstraint: Boolean
|
||||||
|
): Boolean {
|
||||||
checkSubtypeForSpecialCases(subType.lowerBoundIfFlexible(), superType.upperBoundIfFlexible())?.let {
|
checkSubtypeForSpecialCases(subType.lowerBoundIfFlexible(), superType.upperBoundIfFlexible())?.let {
|
||||||
addSubtypeConstraint(subType, superType)
|
addSubtypeConstraint(subType, superType, isFromNullabilityConstraint)
|
||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
|
|
||||||
// we should add constraints with flexible types, otherwise we never get flexible type as answer in constraint system
|
// we should add constraints with flexible types, otherwise we never get flexible type as answer in constraint system
|
||||||
addSubtypeConstraint(subType, superType)?.let { return it }
|
addSubtypeConstraint(subType, superType, isFromNullabilityConstraint)?.let { return it }
|
||||||
|
|
||||||
return isSubtypeOfForSingleClassifierType(subType.lowerBoundIfFlexible(), superType.upperBoundIfFlexible())
|
return isSubtypeOfForSingleClassifierType(subType.lowerBoundIfFlexible(), superType.upperBoundIfFlexible())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user