[FIR] Keep vararg argument order in resolved calls (KT-17691).

This commit is contained in:
Mark Punzalan
2020-09-24 13:43:18 -07:00
committed by teamcityserver
parent f6ce2d893c
commit eb631bc429
14 changed files with 265 additions and 14 deletions
@@ -0,0 +1,41 @@
// IGNORE_BACKEND_FIR: JVM_IR
// Currently fails as the indices (`va`) are evaluated twice (on get and set).
var log = ""
fun logged(value: String) =
value.also { log += value }
object A {
var x = ""
var gets = ""
var sets = ""
operator fun get(vararg va: String): String {
for (s in va) {
gets += s
}
log += "get;"
return x
}
operator fun set(vararg va: String, value: String) {
for (s in va) {
sets += s
}
log += "set;"
x = value
}
}
operator fun String.inc() = this + logged("inc;")
fun box(): String {
A.x = "start;"
val xx = A[logged("1;"), logged("2;"), logged("3;")]++
if (xx != "start;") return "Failed xx: $xx"
if (A.x != "start;inc;") return "Failed A.x: ${A.x}"
if (A.gets != "1;2;3;") return "Failed A.gets: ${A.gets}"
if (A.sets != "1;2;3;") return "Failed A.sets: ${A.sets}"
if (log != "1;2;3;get;inc;set;") return "Failed log: $log"
return "OK"
}
@@ -19,6 +19,7 @@ fun foo3(
) = "$p1 $p2 ${p3[0].toInt()} ${p3[1].toInt()}"
fun box(): String {
if (foo1(1, 2, p2 = "3", p3 = 4.0) != "1 2 3 4") return "fail 1"
if (foo1(p1 = *intArrayOf(1, 2), "3", p3 = 4.0) != "1 2 3 4") return "fail 2"
if (foo2(p1 = 1, "2", "3", p3 = 4.0) != "1 2 3 4") return "fail 3"
@@ -0,0 +1,46 @@
// !LANGUAGE: +NewInference +MixedNamedArgumentsInTheirOwnPosition
// IGNORE_BACKEND: JVM
// See KT-17691: Wrong argument order in resolved call with varargs. (fixed in JVM_IR)
var log = ""
fun <T> logged(value: T): T =
value.also { log += " " + value }
fun doTest(id: String, expected: String, expectedLog: String, test: () -> String) {
log = ""
val actual = test()
if (actual != expected) throw AssertionError("$id expected: $expected, actual: $actual")
if (log != expectedLog) throw AssertionError("$id expectedLog: $expectedLog, actual: $log")
}
fun foo1(
vararg p1: Int,
p2: String,
p3: Double
) = "${p1[0]} ${p1[1]} $p2 ${p3.toInt()}"
fun foo2(
p1: Int,
vararg p2: String,
p3: Double
) = "$p1 ${p2[0]} ${p2[1]} ${p3.toInt()}"
fun foo3(
p1: Int,
p2: String,
vararg p3: Double
) = "$p1 $p2 ${p3[0].toInt()} ${p3[1].toInt()}"
fun box(): String {
doTest("test1", "1 2 3 4", " 1 2 3 4.5") { foo1(logged(1), logged(2), p2 = logged("3"), p3 = logged(4.5)) }
doTest("test2", "1 2 3 4", " 1 2 3 4.5") { foo1(p1 = *intArrayOf(logged(1), logged(2)), logged("3"), p3 = logged(4.5)) }
doTest("test3", "1 2 3 4", " 1 2 3 4.5") { foo2(p1 = logged(1), logged("2"), logged("3"), p3 = logged(4.5)) }
doTest("test4", "1 2 3 4", " 1 2 3 4.5") { foo2(logged(1), p2 = *arrayOf(logged("2"), logged("3")), logged(4.5)) }
doTest("test5", "1 2 3 4", " 1 2 3.5 4.5") { foo3(p1 = logged(1), logged("2"), logged(3.5), logged(4.5)) }
doTest("test6", "1 2 3 4", " 1 2 3.5 4.5") { foo3(p1 = logged(1), logged("2"), p3 = *doubleArrayOf(logged(3.5), logged(4.5))) }
return "OK"
}
+45
View File
@@ -0,0 +1,45 @@
var log = ""
fun <T> logged(value: T): T =
value.also { log += value }
fun doTest(id: String, expected: String, expectedLog: String, test: () -> String) {
log = ""
val actual = test()
if (actual != expected) throw AssertionError("$id expected: $expected, actual: $actual")
if (log != expectedLog) throw AssertionError("$id expectedLog: $expectedLog, actual: $log")
}
object A {
var sets = ""
fun f(vararg va: String, a: String = "default_a;", b: String): String {
var ret = ""
for (s in va) {
ret += s
}
return ret + a + b
}
operator fun set(vararg va: String, value: String) {
for (s in va) {
sets += s
}
log += "set=$value;"
}
}
operator fun String.inc() = this + logged("inc;")
fun box(): String {
doTest("test1", "1;2;3;", "1;2;3;value;set=value;;") {
A[logged("1;"), logged("2;"), logged("3;")] = logged("value;")
A.sets
}
doTest("test2", "1;2;3;default_a;b;", "1;2;3;b;") { A.f(logged("1;"), logged("2;"), logged("3;"), b = logged("b;")) }
doTest("test3", "1;2;3;a;b;", "1;2;3;b;a;") { A.f(logged("1;"), logged("2;"), logged("3;"), b = logged("b;"), a = logged("a;")) }
doTest("test4", "1;2;3;a;b;", "1;2;3;a;b;") { A.f(logged("1;"), logged("2;"), logged("3;"), a = logged("a;"), b = logged("b;")) }
return "OK"
}