JVM: Fix default parameter values handling

When we generate call for 'foo', we make decision about invoking
a 'foo$default' too late, after the call arguments are generated.
If 'foo' was an override, and base class (interface) was generic,
'foo' in base class could have a different Kotlin and JVM
signature, so the arguments we generated could be generated wrong
(primitive or inline class values instead of boxes, see KT-38680).
Also, we always selected first base class in supertypes list,
which caused KT-15971.

Look into resolved call and see if we should actually call
'foo$default' instead of 'foo' when determining actual callable.

Overrides can't introduce default parameter values, and
override-equivalent inherited methods with default parameters
is an error in a child class. Thus, if we are calling a class
member function with a default parameters, there should be one
and only one overridden function that has default parameter values
and overrides nothing.
This commit is contained in:
Dmitry Petrov
2020-05-12 18:42:27 +03:00
parent dc9f64fc9d
commit 2f82c5b6af
21 changed files with 188 additions and 62 deletions
@@ -1,6 +1,3 @@
// IGNORE_BACKEND: JVM
// See KT-15971
interface Foo {
fun foo(a: Double = 1.0): Double
}
@@ -1,5 +1,4 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM
interface Q {
fun foo(a: Double): Double
}
@@ -1,5 +1,4 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM
interface Q {
fun foo(a: Double) = 0.0
}
@@ -1,5 +1,4 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM
interface Q {
fun foo(a: Double): Double
}
@@ -1,5 +1,4 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM
interface I<T> {
val prop: T
@@ -1,5 +1,4 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM
interface I<T> {
val prop: T
@@ -1,5 +1,4 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM
interface I<T> {
val prop: T
@@ -1,5 +1,4 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM
var log = ""
fun log(a: String) {
+15
View File
@@ -0,0 +1,15 @@
// !LANGUAGE: +InlineClasses
inline class IC(val s: String)
interface IFoo<T> {
fun foo(x: T, s: String = "K"): String
fun bar(x: T) = foo(x)
}
class FooImpl : IFoo<IC> {
override fun foo(x: IC, s: String): String = x.s + s
}
fun box(): String = FooImpl().bar(IC("O"))
+17
View File
@@ -0,0 +1,17 @@
// !LANGUAGE: +InlineClasses
inline class IC(val s: String)
interface IFoo<T> {
fun foo(x: T, s: String = "K"): String
}
interface IFoo2<T> : IFoo<T> {
fun bar(x: T) = foo(x)
}
class FooImpl : IFoo2<IC> {
override fun foo(x: IC, s: String): String = x.s + s
}
fun box(): String = FooImpl().bar(IC("O"))
@@ -1,6 +1,5 @@
// !LANGUAGE: +MultiPlatformProjects
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM
// FILE: lib.kt