K1: introduce BUILDER_INFERENCE_STUB_PARAMETER_TYPE to prevent compiler crashes

This diagnostic is reported in rare situations when
StubTypeForBuilderInference is kept as a parameter type
of for loop or lambda. Before this commit, we had in K1
"Could not load module <error module>" from IrLinker instead.

Related to: KT-52757, KT-53109, KT-63841, KT-64066
#KT-53478 Fixed
This commit is contained in:
Mikhail Glukhikh
2024-02-26 10:06:29 +01:00
committed by Space Team
parent 6f6e37f552
commit 678816f9e8
44 changed files with 554 additions and 15 deletions
@@ -0,0 +1,28 @@
// ISSUE: KT-52757
// CHECK_TYPE_WITH_EXACT
fun test() {
val buildee = build {
typeVariableConsumer = ::consumeTargetType
typeVariableConsumer = {}
}
// exact type equality check — turns unexpected compile-time behavior into red code
// considered to be non-user-reproducible code for the purposes of these tests
checkExactType<Buildee<TargetType>>(buildee)
}
class TargetType
fun consumeTargetType(value: TargetType) {}
class Buildee<TV> {
var typeVariableConsumer: (TV) -> Unit = { storage = it }
private var storage: TV = null!!
}
fun <PTV> build(instructions: Buildee<PTV>.() -> Unit): Buildee<PTV> {
return Buildee<PTV>().apply(instructions)
}
@@ -1,11 +1,10 @@
// ISSUE: KT-52757
// FIR_IDENTICAL
// CHECK_TYPE_WITH_EXACT
fun test() {
val buildee = build {
typeVariableConsumer = ::consumeTargetType
typeVariableConsumer = {}
typeVariableConsumer = <!BUILDER_INFERENCE_STUB_PARAMETER_TYPE!>{}<!>
}
// exact type equality check — turns unexpected compile-time behavior into red code
// considered to be non-user-reproducible code for the purposes of these tests
@@ -0,0 +1,27 @@
// ISSUE: KT-53109
// CHECK_TYPE_WITH_EXACT
fun test() {
val buildee = build {
typeVariableConsumer = { consumeTargetType(it) }
}
// exact type equality check — turns unexpected compile-time behavior into red code
// considered to be non-user-reproducible code for the purposes of these tests
checkExactType<Buildee<TargetType>>(buildee)
}
class TargetType
fun consumeTargetType(value: TargetType) {}
class Buildee<TV> {
var typeVariableConsumer: (TV) -> Unit = { storage = it }
private var storage: TV = null!!
}
fun <PTV> build(instructions: Buildee<PTV>.() -> Unit): Buildee<PTV> {
return Buildee<PTV>().apply(instructions)
}
@@ -1,10 +1,9 @@
// ISSUE: KT-53109
// FIR_IDENTICAL
// CHECK_TYPE_WITH_EXACT
fun test() {
val buildee = build {
typeVariableConsumer = { consumeTargetType(it) }
typeVariableConsumer = <!BUILDER_INFERENCE_STUB_PARAMETER_TYPE!>{ consumeTargetType(it) }<!>
}
// exact type equality check — turns unexpected compile-time behavior into red code
// considered to be non-user-reproducible code for the purposes of these tests
@@ -0,0 +1,16 @@
// ISSUE: KT-53478
class UncompilingClass<T : Any>(
val block: (UncompilingClass<T>.() -> Unit)? = null,
) {
var uncompilingFun: ((T) -> Unit)? = null
}
fun handleInt(arg: Int) = Unit
fun box() {
val obj = UncompilingClass {
uncompilingFun = { handleInt(it) }
}
}
@@ -0,0 +1,16 @@
// ISSUE: KT-53478
class UncompilingClass<T : Any>(
val block: (UncompilingClass<T>.() -> Unit)? = null,
) {
var uncompilingFun: ((T) -> Unit)? = null
}
fun handleInt(arg: Int) = Unit
fun box() {
val obj = UncompilingClass {
uncompilingFun = <!BUILDER_INFERENCE_STUB_PARAMETER_TYPE!>{ handleInt(it) }<!>
}
}
@@ -0,0 +1,9 @@
// WITH_STDLIB
// ISSUE: KT-64066
fun box() {
val map = buildMap {
put(1, 1)
for (v in values) {}
}
}
@@ -0,0 +1,9 @@
// WITH_STDLIB
// ISSUE: KT-64066
fun box() {
val map = buildMap {
put(1, 1)
for (<!BUILDER_INFERENCE_STUB_PARAMETER_TYPE!>v<!> in values) {}
}
}
@@ -0,0 +1,26 @@
// FIR_IDENTICAL
// WITH_STDLIB
// ISSUE: KT-64066, KT-53478
// LANGUAGE: +NoBuilderInferenceWithoutAnnotationRestriction
fun box1() {
val map = buildMap {
put(1, 1)
for (v in values) {}
}
}
class UncompilingClass<T : Any>(
val block: (UncompilingClass<T>.() -> Unit)? = null,
) {
var uncompilingFun: ((T) -> Unit)? = null
}
fun handleInt(arg: Int) = Unit
fun box2() {
val obj = UncompilingClass {
uncompilingFun = { handleInt(it) }
}
}