KT-10939 CANNOT_COMPLETE_RESOLVE for inherited generic interface method

'original' for value parameters of fake override is not a value parameter of unsubstituted fake override.
Match value parameters by index.
This commit is contained in:
Dmitry Petrov
2016-02-05 16:02:47 +03:00
parent 9f786c00a7
commit 5968ce96df
7 changed files with 130 additions and 4 deletions
@@ -69,6 +69,7 @@ class CandidateCallWithArgumentMapping<D : CallableDescriptor, K> private constr
val argumentsToParameters = hashMapOf<K, ValueParameterDescriptor>()
var parametersWithDefaultValuesCount = 0
val unsubstitutedValueParameters = call.candidateDescriptor.original.valueParameters
for ((valueParameterDescriptor, resolvedValueArgument) in call.unsubstitutedValueArguments.entries) {
if (resolvedValueArgument is DefaultValueArgument) {
parametersWithDefaultValuesCount++
@@ -76,7 +77,10 @@ class CandidateCallWithArgumentMapping<D : CallableDescriptor, K> private constr
else {
val keys = resolvedArgumentToKeys(resolvedValueArgument)
for (argumentKey in keys) {
argumentsToParameters[argumentKey] = valueParameterDescriptor.original
// TODO fix 'original' for value parameters of Java generic descriptors.
// Should be able to use just 'valueParameterDescriptor' below.
// Doesn't work for Java generic descriptors. See also KT-10939.
argumentsToParameters[argumentKey] = unsubstitutedValueParameters[valueParameterDescriptor.index]
}
}
}
@@ -326,9 +326,6 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
private fun getVarargElementTypeOrType(parameterDescriptor: ValueParameterDescriptor): KotlinType =
parameterDescriptor.varargElementType ?: parameterDescriptor.type
private val CallableDescriptor.hasVarargs: Boolean get() =
this.valueParameters.any { it.varargElementType != null }
private fun typeNotLessSpecific(specific: KotlinType, general: KotlinType): Boolean {
val isSubtype = KotlinTypeChecker.DEFAULT.isSubtypeOf(specific, general) || numericTypeMoreSpecific(specific, general)
@@ -0,0 +1,17 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE
// FILE: Base.java
public interface Base {
<T> String foo(T a);
<T> int foo(T a, Object... args);
}
// FILE: Derived.java
public interface Derived extends Base {
}
// FILE: test.kt
fun testDerived(base: Base, derived: Derived) {
val test1: String = base.foo("")
val test2: String = derived.foo("")
}
@@ -0,0 +1,19 @@
package
public fun testDerived(/*0*/ base: Base, /*1*/ derived: Derived): kotlin.Unit
public interface Base {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun </*0*/ T : kotlin.Any!> foo(/*0*/ a: T!): kotlin.String!
public abstract fun </*0*/ T : kotlin.Any!> foo(/*0*/ a: T!, /*1*/ vararg args: kotlin.Any! /*kotlin.Array<(out) kotlin.Any!>!*/): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Derived : Base {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*1*/ /*fake_override*/ fun </*0*/ T : kotlin.Any!> foo(/*0*/ a: T!): kotlin.String!
public abstract override /*1*/ /*fake_override*/ fun </*0*/ T : kotlin.Any!> foo(/*0*/ a: T!, /*1*/ vararg args: kotlin.Any! /*kotlin.Array<(out) kotlin.Any!>!*/): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
+28
View File
@@ -0,0 +1,28 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE
object X1
object X2
interface Base {
fun <T1> foo(a: T1): X1
fun <T2> foo(a: T2, vararg args: Any): X2
}
interface Derived : Base
fun testDerived(base: Base, derived: Derived) {
val test1: X1 = base.foo("")
val test2: X1 = derived.foo("")
}
interface GenericBase<T> {
fun <T1> foo(x: T, a: T1): X1
}
interface SpecializedDerived : GenericBase<String> {
fun <T2> foo(x: String, a: T2, vararg args: Any): X2
}
fun testSpecializedDerived(derived: SpecializedDerived) {
val test1: X1 = derived.foo("", "")
}
@@ -0,0 +1,49 @@
package
public fun testDerived(/*0*/ base: Base, /*1*/ derived: Derived): kotlin.Unit
public fun testSpecializedDerived(/*0*/ derived: SpecializedDerived): kotlin.Unit
public interface Base {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun </*0*/ T1> foo(/*0*/ a: T1): X1
public abstract fun </*0*/ T2> foo(/*0*/ a: T2, /*1*/ vararg args: kotlin.Any /*kotlin.Array<out kotlin.Any>*/): X2
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Derived : Base {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*1*/ /*fake_override*/ fun </*0*/ T1> foo(/*0*/ a: T1): X1
public abstract override /*1*/ /*fake_override*/ fun </*0*/ T2> foo(/*0*/ a: T2, /*1*/ vararg args: kotlin.Any /*kotlin.Array<out kotlin.Any>*/): X2
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface GenericBase</*0*/ T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun </*0*/ T1> foo(/*0*/ x: T, /*1*/ a: T1): X1
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface SpecializedDerived : GenericBase<kotlin.String> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*1*/ /*fake_override*/ fun </*0*/ T1> foo(/*0*/ x: kotlin.String, /*1*/ a: T1): X1
public abstract fun </*0*/ T2> foo(/*0*/ x: kotlin.String, /*1*/ a: T2, /*2*/ vararg args: kotlin.Any /*kotlin.Array<out kotlin.Any>*/): X2
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
}
@@ -11715,6 +11715,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("kt10939.kt")
public void testKt10939() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/overload/kt10939.kt");
doTest(fileName);
}
@TestMetadata("kt1998.kt")
public void testKt1998() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/overload/kt1998.kt");
@@ -11768,6 +11774,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/overload/TypeParameterMultipleBounds.kt");
doTest(fileName);
}
@TestMetadata("UnsubstitutedJavaGenetics.kt")
public void testUnsubstitutedJavaGenetics() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/overload/UnsubstitutedJavaGenetics.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/diagnostics/tests/override")