Fix SAM detection algorithm for case of default overrides
#KT-22652 Fixed
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
// FILE: ALambda.java
|
||||
|
||||
public interface ALambda {
|
||||
ALambda curried();
|
||||
|
||||
ALambda tupled();
|
||||
}
|
||||
|
||||
// FILE: ACheckedFunction0.java
|
||||
|
||||
public interface ACheckedFunction0 extends ALambda {
|
||||
|
||||
Integer apply();
|
||||
|
||||
default ALambda curried() { return null; }
|
||||
default ALambda tupled() { return null; }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
fun test() {
|
||||
ACheckedFunction0 { 2 } // error: Interface ACheckedFunction0 does not have constructors
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package
|
||||
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
public interface ACheckedFunction0 : ALambda {
|
||||
public abstract fun apply(): kotlin.Int!
|
||||
public open override /*1*/ fun curried(): ALambda!
|
||||
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 override /*1*/ fun tupled(): ALambda!
|
||||
}
|
||||
|
||||
public interface ALambda {
|
||||
public abstract fun curried(): ALambda!
|
||||
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 abstract fun tupled(): ALambda!
|
||||
}
|
||||
@@ -13230,6 +13230,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/sam/typeInferenceOnSamAdapters.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withDefaultMethods.kt")
|
||||
public void testWithDefaultMethods() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/sam/withDefaultMethods.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/j+k/samByProjectedType")
|
||||
|
||||
Generated
+6
@@ -13230,6 +13230,12 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/sam/typeInferenceOnSamAdapters.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withDefaultMethods.kt")
|
||||
public void testWithDefaultMethods() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/sam/withDefaultMethods.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/j+k/samByProjectedType")
|
||||
|
||||
+3
@@ -140,6 +140,9 @@ class LazyJavaClassDescriptor(
|
||||
// we'll just say that the interface MAY BE a SAM when it's not and then more detailed check will be applied.
|
||||
if (candidates.count { it.name.identifier !in PUBLIC_METHOD_NAMES_IN_OBJECT } > 1) return true
|
||||
|
||||
// If we have default methods the interface could be a SAM even while a super interface has more than one abstract method
|
||||
if (jClass.methods.any { !it.isAbstract && it.typeParameters.isEmpty() }) return false
|
||||
|
||||
// Check if any of the super-interfaces contain too many methods to be a SAM
|
||||
return typeConstructor.supertypes.any {
|
||||
it.constructor.declarationDescriptor.safeAs<LazyJavaClassDescriptor>()?.isDefinitelyNotSamInterface == true
|
||||
|
||||
Reference in New Issue
Block a user