Constraint system builder shouldn't drop nullability when comparing signatures for specificity.
This commit is contained in:
+23
-7
@@ -37,7 +37,12 @@ import org.jetbrains.kotlin.types.typeUtil.defaultProjections
|
||||
import org.jetbrains.kotlin.types.typeUtil.isDefaultBound
|
||||
import java.util.*
|
||||
|
||||
class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
class ConstraintSystemBuilderImpl(private val mode: Mode = ConstraintSystemBuilderImpl.Mode.INFERENCE) : ConstraintSystem.Builder {
|
||||
enum class Mode {
|
||||
INFERENCE,
|
||||
SPECIFICITY
|
||||
}
|
||||
|
||||
internal data class Constraint(
|
||||
val kind: ConstraintKind, val subtype: KotlinType, val superType: KotlinType, val position: ConstraintPosition
|
||||
)
|
||||
@@ -217,15 +222,13 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
generateTypeParameterBound(superType, subType, constraintKind.bound.reverse(), constraintContext)
|
||||
return
|
||||
}
|
||||
// if subType is nullable and superType is not nullable, unsafe call or type mismatch error will be generated later,
|
||||
// but constraint system should be solved anyway
|
||||
val subTypeNotNullable = if (constraintContext.initial) TypeUtils.makeNotNullable(subType) else subType
|
||||
val superTypeNotNullable = if (constraintContext.initial) TypeUtils.makeNotNullable(superType) else superType
|
||||
val subType2 = simplifyType(subType, constraintContext.initial)
|
||||
val superType2 = simplifyType(superType, constraintContext.initial)
|
||||
val result = if (constraintKind == EQUAL) {
|
||||
typeCheckingProcedure.equalTypes(subTypeNotNullable, superTypeNotNullable)
|
||||
typeCheckingProcedure.equalTypes(subType2, superType2)
|
||||
}
|
||||
else {
|
||||
typeCheckingProcedure.isSubtypeOf(subTypeNotNullable, superType)
|
||||
typeCheckingProcedure.isSubtypeOf(subType2, superType)
|
||||
}
|
||||
if (!result) errors.add(newTypeInferenceOrParameterConstraintError(constraintPosition))
|
||||
}
|
||||
@@ -237,6 +240,15 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
simplifyConstraint(newSubType, superType)
|
||||
}
|
||||
|
||||
private fun simplifyType(type: KotlinType, isInitialConstraint: Boolean): KotlinType =
|
||||
if (mode == Mode.SPECIFICITY || !isInitialConstraint)
|
||||
type
|
||||
else {
|
||||
// if subType is nullable and superType is not nullable, unsafe call or type mismatch error will be generated later,
|
||||
// but constraint system should be solved anyway
|
||||
TypeUtils.makeNotNullable(type)
|
||||
}
|
||||
|
||||
internal fun addBound(
|
||||
typeVariable: TypeVariable,
|
||||
constrainingType: KotlinType,
|
||||
@@ -393,6 +405,10 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
override fun build(): ConstraintSystem {
|
||||
return ConstraintSystemImpl(allTypeParameterBounds, usedInBounds, errors, initialConstraints, typeVariableSubstitutors)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun forSpecificity() = ConstraintSystemBuilderImpl(Mode.SPECIFICITY)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun createTypeForFunctionPlaceholder(
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ fun <T> isSignatureNotLessSpecific(
|
||||
if (specific.valueParameterTypes.size != general.valueParameterTypes.size) return false
|
||||
|
||||
val typeParameters = general.typeParameters
|
||||
val constraintSystemBuilder: ConstraintSystem.Builder = ConstraintSystemBuilderImpl()
|
||||
val constraintSystemBuilder: ConstraintSystem.Builder = ConstraintSystemBuilderImpl.forSpecificity()
|
||||
val typeSubstitutor = constraintSystemBuilder.registerTypeVariables(callHandle, typeParameters)
|
||||
|
||||
var numConstraints = 0
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
<!CONFLICTING_JVM_DECLARATIONS!>fun foo(<!UNUSED_PARAMETER!>x<!>: Array<Int>)<!> {}
|
||||
|
||||
<!CONFLICTING_JVM_DECLARATIONS!>fun foo(vararg <!UNUSED_PARAMETER!>nn<!>: Number)<!> {}
|
||||
<!CONFLICTING_JVM_DECLARATIONS!>fun foo(<!UNUSED_PARAMETER!>nn<!>: Array<out Number>)<!> {}
|
||||
<!CONFLICTING_JVM_DECLARATIONS!>fun foo(<!UNUSED_PARAMETER!>nn<!>: Array<out Number>)<!> {}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
fun <T> List<T>?.foo() {}
|
||||
fun <T1> List<T1>?.foo() {}
|
||||
|
||||
// NB Not a redeclaration
|
||||
@JvmName("f1")
|
||||
fun <T> List<T>.foo() {}
|
||||
@JvmName("foo1")
|
||||
fun <T2> List<T2>.foo() {}
|
||||
|
||||
|
||||
fun <T1> bar(x: List<T1>) = x
|
||||
|
||||
@JvmName("bar1")
|
||||
fun <T2> bar(x: List<T2>?) = x
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
package
|
||||
|
||||
@kotlin.jvm.JvmName(name = "f1") public fun </*0*/ T> kotlin.collections.List<T>.foo(): kotlin.Unit
|
||||
public fun </*0*/ T> kotlin.collections.List<T>?.foo(): kotlin.Unit
|
||||
public fun </*0*/ T1> bar(/*0*/ x: kotlin.collections.List<T1>): kotlin.collections.List<T1>
|
||||
@kotlin.jvm.JvmName(name = "bar1") public fun </*0*/ T2> bar(/*0*/ x: kotlin.collections.List<T2>?): kotlin.collections.List<T2>?
|
||||
public fun </*0*/ T1> kotlin.collections.List<T1>?.foo(): kotlin.Unit
|
||||
@kotlin.jvm.JvmName(name = "foo1") public fun </*0*/ T2> kotlin.collections.List<T2>.foo(): kotlin.Unit
|
||||
|
||||
Reference in New Issue
Block a user