[FIR] Allow to access uninitialized member properties in non-inPlace lambdas in class initialization

^KT-56696 Fixed
^KT-56408
This commit is contained in:
Dmitriy Novozhilov
2023-02-15 19:02:18 +02:00
committed by Space Team
parent 914acd841f
commit 86af01439c
13 changed files with 200 additions and 96 deletions
@@ -0,0 +1,71 @@
// DIAGNOSTICS: -UNUSED_PARAMETER
// WITH_STDLIB
import kotlin.contracts.*
fun capture(block: () -> Unit): String = ""
@OptIn(ExperimentalContracts::class)
inline fun inPlace(block: () -> Unit): String {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return ""
}
fun consume(x: Any?) {}
class A {
val a = capture { consume(x) }
val b = inPlace {
consume(<!UNINITIALIZED_VARIABLE!>x<!>) // error
capture { consume(x) } // ok
inPlace {
consume(<!UNINITIALIZED_VARIABLE!>x<!>) // error
capture { consume(x) } // ok
}
}
val c = object {
fun foo() {
consume(x) // ok
capture { consume(x) } // ok
inPlace {
consume(x) // ok
capture { consume(x) } // ok
}
}
init {
consume(<!UNINITIALIZED_VARIABLE!>x<!>) // error
capture { consume(x) } // ok
inPlace {
consume(<!UNINITIALIZED_VARIABLE!>x<!>) // error
capture { consume(x) } // ok
}
}
val objectProp = inPlace {
consume(<!UNINITIALIZED_VARIABLE!>x<!>) // error
capture { consume(x) } // ok
inPlace {
consume(<!UNINITIALIZED_VARIABLE!>x<!>) // error
capture { consume(x) } // ok
}
}
}
val d = inPlace {
fun localFun() {
consume(x) // ok
}
capture {
localFun()
}
}
val x = 10
}
@@ -0,0 +1,71 @@
// DIAGNOSTICS: -UNUSED_PARAMETER
// WITH_STDLIB
import kotlin.contracts.*
fun capture(block: () -> Unit): String = ""
@OptIn(ExperimentalContracts::class)
inline fun inPlace(block: () -> Unit): String {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return ""
}
fun consume(x: Any?) {}
class A {
val a = capture { consume(x) }
val b = inPlace {
consume(x) // error
capture { consume(x) } // ok
inPlace {
consume(x) // error
capture { consume(x) } // ok
}
}
val c = object {
fun foo() {
consume(x) // ok
capture { consume(x) } // ok
inPlace {
consume(x) // ok
capture { consume(x) } // ok
}
}
init {
consume(<!UNINITIALIZED_VARIABLE!>x<!>) // error
capture { consume(x) } // ok
inPlace {
consume(x) // error
capture { consume(x) } // ok
}
}
val objectProp = inPlace {
consume(x) // error
capture { consume(x) } // ok
inPlace {
consume(x) // error
capture { consume(x) } // ok
}
}
}
val d = inPlace {
fun localFun() {
consume(x) // ok
}
capture {
localFun()
}
}
val x = 10
}
@@ -1,87 +0,0 @@
fun println(obj: Any?) = obj
class Demo0 {
private val some = object {
fun foo() {
println(state)
}
}
private var state: Boolean = true
}
class Demo1 {
private val some = object {
fun foo() {
if (state)
state = true
println(state)
}
}
private var state: Boolean = true
}
class Demo1A {
fun foo() {
if (state)
state = true
println(state)
}
private var state: Boolean = true
}
class Demo2 {
private val some = object {
fun foo() {
if (state)
state = true
else
state = false
println(state)
}
}
private var state: Boolean = true
}
class Demo3 {
private val some = run {
if (state)
state = true
println(state)
}
private var state: Boolean = true
}
fun <T> exec(f: () -> T): T = f()
class Demo4 {
private val some = exec {
if (<!UNINITIALIZED_VARIABLE!>state<!>)
state = true
println(<!UNINITIALIZED_VARIABLE!>state<!>)
}
private var state: Boolean = true
}
class Demo5 {
private var state: Boolean = true
private val some = object {
fun foo() {
if (state)
state = true
println(state)
}
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
fun println(obj: Any?) = obj
class Demo0 {