Check specificity relation for generant types of the constraint system.
Otherwise we can't properly chose between 'dynamic' and generic type.
This commit is contained in:
+17
-10
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.toHandle
|
||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
@@ -149,8 +149,10 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
||||
if (discriminateGenerics) {
|
||||
val isGeneric1 = call1.isGeneric
|
||||
val isGeneric2 = call2.isGeneric
|
||||
// generic loses to non-generic
|
||||
if (isGeneric1 && !isGeneric2) return false
|
||||
if (!isGeneric1 && isGeneric2) return true
|
||||
// two generics are non-comparable
|
||||
if (isGeneric1 && isGeneric2) return false
|
||||
}
|
||||
|
||||
@@ -167,17 +169,20 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
else if (isDefinitelyLessSpecificByTypeSpecificity(type1, type2)) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
hasConstraints = true
|
||||
val substitutedType2 = typeSubstitutor.safeSubstitute(type2, Variance.INVARIANT)
|
||||
constraintSystemBuilder.addSubtypeConstraint(type1, substitutedType2, constraintPosition)
|
||||
hasConstraints = true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
val extensionReceiverType1 = call1.getExtensionReceiverType(false)
|
||||
val extensionReceiverType2 = call2.getExtensionReceiverType(false)
|
||||
if (!compareTypesAndUpdateConstraints(extensionReceiverType1, extensionReceiverType2, ConstraintPositionKind.RECEIVER_POSITION.position())) {
|
||||
if (!compareTypesAndUpdateConstraints(extensionReceiverType1, extensionReceiverType2, RECEIVER_POSITION.position())) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -190,7 +195,7 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
||||
val type1 = call1.getValueParameterType(argumentKey, false)
|
||||
val type2 = call2.getValueParameterType(argumentKey, false)
|
||||
|
||||
if (!compareTypesAndUpdateConstraints(type1, type2, ConstraintPositionKind.VALUE_PARAMETER_POSITION.position(index++))) {
|
||||
if (!compareTypesAndUpdateConstraints(type1, type2, VALUE_PARAMETER_POSITION.position(index++))) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -306,16 +311,18 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
||||
|
||||
if (!isSubtype) return false
|
||||
|
||||
val sThanG = specific.getSpecificityRelationTo(general)
|
||||
val gThanS = general.getSpecificityRelationTo(specific)
|
||||
if (sThanG == Specificity.Relation.LESS_SPECIFIC &&
|
||||
gThanS != Specificity.Relation.LESS_SPECIFIC) {
|
||||
return false
|
||||
}
|
||||
if (isDefinitelyLessSpecificByTypeSpecificity(specific, general)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun isDefinitelyLessSpecificByTypeSpecificity(specific: KotlinType, general: KotlinType): Boolean {
|
||||
val sThanG = specific.getSpecificityRelationTo(general)
|
||||
val gThanS = general.getSpecificityRelationTo(specific)
|
||||
return sThanG == Specificity.Relation.LESS_SPECIFIC &&
|
||||
gThanS != Specificity.Relation.LESS_SPECIFIC
|
||||
}
|
||||
|
||||
private fun numericTypeMoreSpecific(specific: KotlinType, general: KotlinType): Boolean {
|
||||
val _double = builtIns.doubleType
|
||||
val _float = builtIns.floatType
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
object X1
|
||||
object X2
|
||||
|
||||
class Inv<T>
|
||||
|
||||
fun dynamic.foo() = X1
|
||||
fun <T> Inv<T>.foo() = X2
|
||||
|
||||
fun test(): X2 = Inv<Any>().foo()
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package
|
||||
|
||||
public fun test(): X2
|
||||
public fun </*0*/ T> Inv<T>.foo(): X2
|
||||
public fun dynamic.foo(): X1
|
||||
|
||||
public final class Inv</*0*/ T> {
|
||||
public constructor Inv</*0*/ T>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public object X1 {
|
||||
private constructor X1()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public object X2 {
|
||||
private constructor X2()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -115,6 +115,12 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("dynamicVsGeneric.kt")
|
||||
public void testDynamicVsGeneric() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/dynamicVsGeneric.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("extensionVals.kt")
|
||||
public void testExtensionVals() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/extensionVals.kt");
|
||||
|
||||
Reference in New Issue
Block a user