Fix SAM conversions for derived classes
#KT-39535 Fixed #KT-37149 Fixed
This commit is contained in:
+10
@@ -13661,6 +13661,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
|||||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/compatibilityResolveToOuterScopeForKotlinFunctions.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/compatibilityResolveToOuterScopeForKotlinFunctions.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("conversionForDerivedGenericClass.kt")
|
||||||
|
public void testConversionForDerivedGenericClass() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/conversionForDerivedGenericClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("conversionsWithNestedGenerics.kt")
|
||||||
|
public void testConversionsWithNestedGenerics() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/conversionsWithNestedGenerics.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("enhancedSamConstructor.kt")
|
@TestMetadata("enhancedSamConstructor.kt")
|
||||||
public void testEnhancedSamConstructor() throws Exception {
|
public void testEnhancedSamConstructor() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt");
|
||||||
|
|||||||
+12
-9
@@ -64,19 +64,22 @@ object SamTypeConversions : ParameterTypeConversion {
|
|||||||
val callComponents = candidate.callComponents
|
val callComponents = candidate.callComponents
|
||||||
val originalExpectedType = argument.getExpectedType(parameter.original, callComponents.languageVersionSettings)
|
val originalExpectedType = argument.getExpectedType(parameter.original, callComponents.languageVersionSettings)
|
||||||
|
|
||||||
val convertedTypeByOriginal =
|
|
||||||
callComponents.samConversionResolver.getFunctionTypeForPossibleSamType(
|
|
||||||
originalExpectedType,
|
|
||||||
callComponents.samConversionOracle
|
|
||||||
) ?: return null
|
|
||||||
|
|
||||||
val convertedTypeByCandidate =
|
val convertedTypeByCandidate =
|
||||||
callComponents.samConversionResolver.getFunctionTypeForPossibleSamType(
|
callComponents.samConversionResolver.getFunctionTypeForPossibleSamType(
|
||||||
expectedParameterType,
|
expectedParameterType,
|
||||||
callComponents.samConversionOracle
|
callComponents.samConversionOracle
|
||||||
)
|
) ?: return null
|
||||||
|
|
||||||
assert(expectedParameterType.constructor == originalExpectedType.constructor && convertedTypeByCandidate != null) {
|
val convertedTypeByOriginal =
|
||||||
|
if (expectedParameterType.constructor == originalExpectedType.constructor)
|
||||||
|
callComponents.samConversionResolver.getFunctionTypeForPossibleSamType(
|
||||||
|
originalExpectedType,
|
||||||
|
callComponents.samConversionOracle
|
||||||
|
)
|
||||||
|
else
|
||||||
|
convertedTypeByCandidate
|
||||||
|
|
||||||
|
assert(convertedTypeByCandidate.constructor == convertedTypeByOriginal?.constructor) {
|
||||||
"If original type is SAM type, then candidate should have same type constructor and corresponding function type\n" +
|
"If original type is SAM type, then candidate should have same type constructor and corresponding function type\n" +
|
||||||
"originalExpectType: $originalExpectedType, candidateExpectType: $expectedParameterType\n" +
|
"originalExpectType: $originalExpectedType, candidateExpectType: $expectedParameterType\n" +
|
||||||
"functionTypeByOriginal: $convertedTypeByOriginal, functionTypeByCandidate: $convertedTypeByCandidate"
|
"functionTypeByOriginal: $convertedTypeByOriginal, functionTypeByCandidate: $convertedTypeByCandidate"
|
||||||
@@ -84,7 +87,7 @@ object SamTypeConversions : ParameterTypeConversion {
|
|||||||
|
|
||||||
candidate.resolvedCall.registerArgumentWithSamConversion(
|
candidate.resolvedCall.registerArgumentWithSamConversion(
|
||||||
argument,
|
argument,
|
||||||
SamConversionDescription(convertedTypeByOriginal, convertedTypeByCandidate!!)
|
SamConversionDescription(convertedTypeByOriginal!!, convertedTypeByCandidate)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (needCompatibilityResolveForSAM(candidate, expectedParameterType)) {
|
if (needCompatibilityResolveForSAM(candidate, expectedParameterType)) {
|
||||||
|
|||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// FILE: A.java
|
||||||
|
public interface A<T> {
|
||||||
|
void f(T arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: B.java
|
||||||
|
public interface B extends A<Runnable> {}
|
||||||
|
|
||||||
|
// FILE: C.java
|
||||||
|
public class C<K> {
|
||||||
|
public void f(K k) {}
|
||||||
|
public static <R> void g(R r) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
fun test(a: A<Runnable>, b: B, c: C<Runnable>) {
|
||||||
|
a.f { }
|
||||||
|
b.f { }
|
||||||
|
c.f { }
|
||||||
|
C<Runnable>().f { }
|
||||||
|
C.g<Runnable> { }
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// FILE: A.java
|
||||||
|
public interface A<T> {
|
||||||
|
void f(T arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: B.java
|
||||||
|
public interface B extends A<Runnable> {}
|
||||||
|
|
||||||
|
// FILE: C.java
|
||||||
|
public class C<K> {
|
||||||
|
public void f(K k) {}
|
||||||
|
public static <R> void g(R r) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
fun test(a: A<Runnable>, b: B, c: C<Runnable>) {
|
||||||
|
a.f { }
|
||||||
|
b.f { }
|
||||||
|
c.f { }
|
||||||
|
C<Runnable>().f { }
|
||||||
|
C.g<Runnable> <!TYPE_MISMATCH, TYPE_MISMATCH!>{ }<!>
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test(/*0*/ a: A<java.lang.Runnable>, /*1*/ b: B, /*2*/ c: C<java.lang.Runnable>): kotlin.Unit
|
||||||
|
|
||||||
|
public interface A</*0*/ T : kotlin.Any!> {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public abstract fun f(/*0*/ arg: T!): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface B : A<java.lang.Runnable!> {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public abstract override /*1*/ /*fake_override*/ fun f(/*0*/ arg: java.lang.Runnable!): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class C</*0*/ K : kotlin.Any!> {
|
||||||
|
public constructor C</*0*/ K : kotlin.Any!>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun f(/*0*/ k: K!): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public open fun </*0*/ R : kotlin.Any!> g(/*0*/ r: R!): kotlin.Unit
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
|
||||||
|
// FILE: Listener.java
|
||||||
|
public interface Listener<T> {
|
||||||
|
void on(T self);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Base.java
|
||||||
|
public class Base<S, T extends Listener<S>> {
|
||||||
|
public void addListener(T listener) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Derived.java
|
||||||
|
public class Derived extends Base<Derived, Listener<Derived>> {}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
fun test(w: Derived) {
|
||||||
|
w.addListener { _ -> call() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun call() {}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun call(): kotlin.Unit
|
||||||
|
public fun test(/*0*/ w: Derived): kotlin.Unit
|
||||||
|
|
||||||
|
public open class Base</*0*/ S : kotlin.Any!, /*1*/ T : Listener<S!>!> {
|
||||||
|
public constructor Base</*0*/ S : kotlin.Any!, /*1*/ T : Listener<S!>!>()
|
||||||
|
public open fun addListener(/*0*/ listener: T!): kotlin.Unit
|
||||||
|
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 open class Derived : Base<Derived!, Listener<Derived!>!> {
|
||||||
|
public constructor Derived()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun addListener(/*0*/ listener: Listener<Derived!>!): kotlin.Unit
|
||||||
|
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 interface Listener</*0*/ T : kotlin.Any!> {
|
||||||
|
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 abstract fun on(/*0*/ self: T!): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
-18
@@ -1,18 +0,0 @@
|
|||||||
// !LANGUAGE: +NewInference
|
|
||||||
// FILE: J.java
|
|
||||||
public interface J<T> {
|
|
||||||
public void foo(T r1, T r2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: Runnable.java
|
|
||||||
public interface Runnable {
|
|
||||||
void run();
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: 1.kt
|
|
||||||
fun test(j: J<Runnable>, r: Runnable) {
|
|
||||||
j.foo(r, r)
|
|
||||||
j.foo(r, {})
|
|
||||||
j.foo({}, r)
|
|
||||||
j.foo({}, {})
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !LANGUAGE: +NewInference
|
// !LANGUAGE: +NewInference
|
||||||
// FILE: J.java
|
// FILE: J.java
|
||||||
public interface J<T> {
|
public interface J<T> {
|
||||||
@@ -12,7 +13,7 @@ public interface Runnable {
|
|||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
fun test(j: J<Runnable>, r: Runnable) {
|
fun test(j: J<Runnable>, r: Runnable) {
|
||||||
j.foo(r, r)
|
j.foo(r, r)
|
||||||
j.foo(r, <!TYPE_MISMATCH!>{}<!>)
|
j.foo(r, {})
|
||||||
j.foo(<!TYPE_MISMATCH!>{}<!>, r)
|
j.foo({}, r)
|
||||||
j.foo(<!TYPE_MISMATCH!>{}<!>, <!TYPE_MISMATCH!>{}<!>)
|
j.foo({}, {})
|
||||||
}
|
}
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
// !LANGUAGE: +NewInference +SamConversionForKotlinFunctions
|
|
||||||
// FILE: Runnable.java
|
|
||||||
public interface Runnable {
|
|
||||||
void run();
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: 1.kt
|
|
||||||
interface K<T> {
|
|
||||||
fun foo(t1: T, t2: T)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun test(k: K<Runnable>, r: Runnable) {
|
|
||||||
k.foo(r, r)
|
|
||||||
k.foo(r, {})
|
|
||||||
k.foo({}, r)
|
|
||||||
k.foo({}, {})
|
|
||||||
}
|
|
||||||
+4
-3
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !LANGUAGE: +NewInference +SamConversionForKotlinFunctions
|
// !LANGUAGE: +NewInference +SamConversionForKotlinFunctions
|
||||||
// FILE: Runnable.java
|
// FILE: Runnable.java
|
||||||
public interface Runnable {
|
public interface Runnable {
|
||||||
@@ -11,7 +12,7 @@ interface K<T> {
|
|||||||
|
|
||||||
fun test(k: K<Runnable>, r: Runnable) {
|
fun test(k: K<Runnable>, r: Runnable) {
|
||||||
k.foo(r, r)
|
k.foo(r, r)
|
||||||
k.foo(r, <!TYPE_MISMATCH!>{}<!>)
|
k.foo(r, {})
|
||||||
k.foo(<!TYPE_MISMATCH!>{}<!>, r)
|
k.foo({}, r)
|
||||||
k.foo(<!TYPE_MISMATCH!>{}<!>, <!TYPE_MISMATCH!>{}<!>)
|
k.foo({}, {})
|
||||||
}
|
}
|
||||||
@@ -13668,6 +13668,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
|
|||||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/compatibilityResolveToOuterScopeForKotlinFunctions.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/compatibilityResolveToOuterScopeForKotlinFunctions.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("conversionForDerivedGenericClass.kt")
|
||||||
|
public void testConversionForDerivedGenericClass() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/conversionForDerivedGenericClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("conversionsWithNestedGenerics.kt")
|
||||||
|
public void testConversionsWithNestedGenerics() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/conversionsWithNestedGenerics.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("enhancedSamConstructor.kt")
|
@TestMetadata("enhancedSamConstructor.kt")
|
||||||
public void testEnhancedSamConstructor() throws Exception {
|
public void testEnhancedSamConstructor() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt");
|
||||||
|
|||||||
Generated
+10
@@ -13663,6 +13663,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
|||||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/compatibilityResolveToOuterScopeForKotlinFunctions.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/compatibilityResolveToOuterScopeForKotlinFunctions.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("conversionForDerivedGenericClass.kt")
|
||||||
|
public void testConversionForDerivedGenericClass() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/conversionForDerivedGenericClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("conversionsWithNestedGenerics.kt")
|
||||||
|
public void testConversionsWithNestedGenerics() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/conversionsWithNestedGenerics.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("enhancedSamConstructor.kt")
|
@TestMetadata("enhancedSamConstructor.kt")
|
||||||
public void testEnhancedSamConstructor() throws Exception {
|
public void testEnhancedSamConstructor() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user