[PL] Handle illegal fun interface SAM conversions

^KT-53967
This commit is contained in:
Dmitriy Dolovov
2023-05-17 17:38:21 +02:00
committed by Space Team
parent 7f4d9ddde5
commit 1536bca1bb
7 changed files with 225 additions and 20 deletions
+13 -4
View File
@@ -133,10 +133,6 @@ class ClassToValue(val x: Int)
data class DataToClass(val x: Int, val y: Int)
fun interface FunctionalInterfaceToInterface {
fun work()
}
class ClassToAbstractClass {
var name: String = "Alice"
fun getGreeting() = "Hello, $name!"
@@ -150,3 +146,16 @@ object PublicTopLevelLib1 {
class ClassThatBecomesPrivate
enum class EnumClassThatBecomesPrivate { ENTRY }
}
interface XAnswer { fun answer(): Int }
interface XAnswerDefault { fun answer(): Int /*= 42*/ }
interface XFunction1 { /*fun function1(): Int*/ }
interface XFunction1Default { /*fun function1(): Int = 42*/ }
interface XFunction2 { /*fun function2(): Int*/ }
interface XFunction2Default { /*fun function2(): Int = -42*/ }
interface XProperty1 { /*val property1: Int*/ }
interface XProperty1Default { /*val property1: Int get() = 42*/ }
interface XProperty2 { /*val property2: Int*/ }
interface XProperty2Default { /*val property2: Int get() = 42*/ }
fun interface FunctionalInterfaceToInterface : XAnswer
+13 -4
View File
@@ -133,10 +133,6 @@ value class ClassToValue(val x: Int)
/*data*/ class DataToClass(val x: Int, val y: Int)
/*fun*/ interface FunctionalInterfaceToInterface {
fun work()
}
abstract class ClassToAbstractClass {
abstract var name: String
fun getGreeting() = "Hello, $name!"
@@ -150,3 +146,16 @@ object PublicTopLevelLib1 {
private class ClassThatBecomesPrivate
private enum class EnumClassThatBecomesPrivate { ENTRY }
}
interface XAnswer { fun answer(): Int }
interface XAnswerDefault { fun answer(): Int /*= 42*/ }
interface XFunction1 { fun function1(): Int }
interface XFunction1Default { fun function1(): Int = 42 }
interface XFunction2 { fun function2(): Int }
interface XFunction2Default { fun function2(): Int = -42 }
interface XProperty1 { val property1: Int }
interface XProperty1Default { val property1: Int get() = 42 }
interface XProperty2 { val property2: Int }
interface XProperty2Default { val property2: Int get() = 42 }
/*fun*/ interface FunctionalInterfaceToInterface : XAnswer
+103 -6
View File
@@ -1,3 +1,4 @@
fun getClassToEnumFoo(): ClassToEnum.Foo = ClassToEnum.Foo()
inline fun getClassToEnumFooInline(): ClassToEnum.Foo = ClassToEnum.Foo()
fun getClassToEnumFooAsAny(): Any = ClassToEnum.Foo()
@@ -378,12 +379,6 @@ fun getSumFromDataClass(): Int {
return x + y
}
fun getFunctionalInterfaceToInterface(): FunctionalInterfaceToInterface {
val worker = FunctionalInterfaceToInterface { /* do some work */ }
worker.work()
return worker
}
fun instantiationOfAbstractClass() {
// Accessing uninitialized members of abstract class is an UB. We shall not allow instantiating
// abstract classes except for from their direct inheritors.
@@ -424,3 +419,105 @@ class StableInheritorOfClassThatUsesPrivateTopLevelClass : AbstractIterator<Stri
fun testStableInheritorOfClassThatUsesPrivateTopLevelClass(): String = buildString {
for (s in StableInheritorOfClassThatUsesPrivateTopLevelClass()) append(s)
}
fun getFunctionalInterfaceToInterface(answer: Int): FunctionalInterfaceToInterface {
val worker = FunctionalInterfaceToInterface { answer }
return worker
}
fun getFunctionalInterfaceToInterfaceAsObject(answer: Int): FunctionalInterfaceToInterface {
val worker = object : FunctionalInterfaceToInterface {
override fun answer() = answer
}
return worker
}
fun getFunctionalInterfaceToInterfaceAnswer(answer: Int): Int {
return getFunctionalInterfaceToInterface(answer).answer()
}
fun interface FunctionalInterfaceWith0AbstractFunctions : XAnswerDefault
fun interface FunctionalInterfaceWith1AbstractFunction : XAnswer, XFunction1Default, XFunction2Default, XProperty1Default, XProperty2Default
fun interface FunctionalInterfaceWith2AbstractFunctions : XAnswer, XFunction1, XFunction2Default, XProperty1Default, XProperty2Default
fun interface FunctionalInterfaceWith3AbstractFunctions : XAnswer, XFunction1, XFunction2, XProperty1Default, XProperty2Default
fun interface FunctionalInterfaceWithAbstractProperty : XAnswer, XFunction1Default, XFunction2Default, XProperty1, XProperty2Default
fun getFunctionalInterfaceWith0AbstractFunctions(answer: Int): FunctionalInterfaceWith0AbstractFunctions {
val worker = FunctionalInterfaceWith0AbstractFunctions { answer }
return worker
}
fun getFunctionalInterfaceWith0AbstractFunctionsAsObject(answer: Int): FunctionalInterfaceWith0AbstractFunctions {
val worker = object : FunctionalInterfaceWith0AbstractFunctions {
override fun answer() = answer
}
return worker
}
fun getFunctionalInterfaceWith0AbstractFunctionsAnswer(answer: Int): Int {
return getFunctionalInterfaceWith0AbstractFunctions(answer).answer()
}
fun getFunctionalInterfaceWith1AbstractFunction(answer: Int): FunctionalInterfaceWith1AbstractFunction {
val worker = FunctionalInterfaceWith1AbstractFunction { answer }
return worker
}
fun getFunctionalInterfaceWith1AbstractFunctionAsObject(answer: Int): FunctionalInterfaceWith1AbstractFunction {
val worker = object : FunctionalInterfaceWith1AbstractFunction {
override fun answer() = answer
}
return worker
}
fun getFunctionalInterfaceWith1AbstractFunctionAnswer(answer: Int): Int {
return getFunctionalInterfaceWith1AbstractFunction(answer).answer()
}
fun getFunctionalInterfaceWith2AbstractFunctions(answer: Int): FunctionalInterfaceWith2AbstractFunctions {
val worker = FunctionalInterfaceWith2AbstractFunctions { answer }
return worker
}
fun getFunctionalInterfaceWith2AbstractFunctionsAsObject(answer: Int): FunctionalInterfaceWith2AbstractFunctions {
val worker = object : FunctionalInterfaceWith2AbstractFunctions {
override fun answer() = answer
}
return worker
}
fun getFunctionalInterfaceWith2AbstractFunctionsAnswer(answer: Int): Int {
return getFunctionalInterfaceWith2AbstractFunctions(answer).answer()
}
fun getFunctionalInterfaceWith3AbstractFunctions(answer: Int): FunctionalInterfaceWith3AbstractFunctions {
val worker = FunctionalInterfaceWith3AbstractFunctions { answer }
return worker
}
fun getFunctionalInterfaceWith3AbstractFunctionsAsObject(answer: Int): FunctionalInterfaceWith3AbstractFunctions {
val worker = object : FunctionalInterfaceWith3AbstractFunctions {
override fun answer() = answer
}
return worker
}
fun getFunctionalInterfaceWith3AbstractFunctionsAnswer(answer: Int): Int {
return getFunctionalInterfaceWith3AbstractFunctions(answer).answer()
}
fun getFunctionalInterfaceWithAbstractProperty(answer: Int): FunctionalInterfaceWithAbstractProperty {
val worker = FunctionalInterfaceWithAbstractProperty { answer }
return worker
}
fun getFunctionalInterfaceWithAbstractPropertyAsObject(answer: Int): FunctionalInterfaceWithAbstractProperty {
val worker = object : FunctionalInterfaceWithAbstractProperty {
override fun answer() = answer
}
return worker
}
fun getFunctionalInterfaceWithAbstractPropertyAnswer(answer: Int): Int {
return getFunctionalInterfaceWithAbstractProperty(answer).answer()
}
+19 -2
View File
@@ -333,12 +333,29 @@ fun box() = abiTest {
expectFailure(linkage("Function 'component1' can not be called: No function found for symbol '/DataToClass.component1'")) { getSumFromDataClass() }
expectSuccess { getFunctionalInterfaceToInterface(); "OK" }
expectFailure(linkage("Constructor 'ClassToAbstractClass.<init>' can not be called: Can not instantiate abstract class 'ClassToAbstractClass'")) { instantiationOfAbstractClass() }
expectSuccess { StableEnum.FOO.test }
expectSuccess { StableEnum.BAR.test }
expectSuccess("01234") { testStableInheritorOfClassThatUsesPrivateTopLevelClass() }
expectSuccess(1) { getFunctionalInterfaceToInterface(1).answer() }
expectSuccess(2) { getFunctionalInterfaceToInterfaceAsObject(2).answer() }
expectSuccess(3) { getFunctionalInterfaceToInterfaceAnswer(3) }
expectSuccess(4) { getFunctionalInterfaceWith0AbstractFunctions(4).answer() }
expectSuccess(5) { getFunctionalInterfaceWith0AbstractFunctionsAsObject(5).answer() }
expectSuccess(6) { getFunctionalInterfaceWith0AbstractFunctionsAnswer(6) }
expectSuccess(7) { getFunctionalInterfaceWith1AbstractFunction(7).answer() }
expectSuccess(8) { getFunctionalInterfaceWith1AbstractFunctionAsObject(8).answer() }
expectSuccess(9) { getFunctionalInterfaceWith1AbstractFunctionAnswer(9) }
expectFailure(linkage("Single abstract method (SAM) conversion expression can not be evaluated: Fun interface 'FunctionalInterfaceWith2AbstractFunctions' has more than one abstract function: 'answer', 'function1'")) { getFunctionalInterfaceWith2AbstractFunctions(10).answer() }
expectSuccess(11) { getFunctionalInterfaceWith2AbstractFunctionsAsObject(11).answer() }
expectFailure(linkage("Single abstract method (SAM) conversion expression can not be evaluated: Fun interface 'FunctionalInterfaceWith2AbstractFunctions' has more than one abstract function: 'answer', 'function1'")) { getFunctionalInterfaceWith2AbstractFunctionsAnswer(12) }
expectFailure(linkage("Single abstract method (SAM) conversion expression can not be evaluated: Fun interface 'FunctionalInterfaceWith3AbstractFunctions' has more than one abstract function: 'answer', 'function1', 'function2'")) { getFunctionalInterfaceWith3AbstractFunctions(13).answer() }
expectSuccess(14) { getFunctionalInterfaceWith3AbstractFunctionsAsObject(14).answer() }
expectFailure(linkage("Single abstract method (SAM) conversion expression can not be evaluated: Fun interface 'FunctionalInterfaceWith3AbstractFunctions' has more than one abstract function: 'answer', 'function1', 'function2'")) { getFunctionalInterfaceWith3AbstractFunctionsAnswer(15) }
expectFailure(linkage("Single abstract method (SAM) conversion expression can not be evaluated: Fun interface 'FunctionalInterfaceWithAbstractProperty' has abstract property 'property1'")) { getFunctionalInterfaceWithAbstractProperty(16).answer() }
expectSuccess(17) { getFunctionalInterfaceWithAbstractPropertyAsObject(17).answer() }
expectFailure(linkage("Single abstract method (SAM) conversion expression can not be evaluated: Fun interface 'FunctionalInterfaceWithAbstractProperty' has abstract property 'property1'")) { getFunctionalInterfaceWithAbstractPropertyAnswer(18) }
}