Use and val initialization

I stumbled upon something that thoroughly confused me. The following code is not legal:

val i: Int
AutoCloseable { }.use { i = 5 }
// Captured values initialization is forbidden due to possible reassignment

Whereas this is fine:

val i: Int
AutoCloseable { }.let { i = 5 }
// also, apply, run ...

Both of these methods return block(this):

public inline fun <T : AutoCloseable?, R> T.use(block: (T) -> R): R {
    var exception: Throwable? = null
    try {
        return block(this)
    } catch (e: Throwable) {
        exception = e
        throw e
    } finally {
        this.closeFinally(exception)
    }
} 

public inline fun <T, R> T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}

Is this an oversight (missing contract)? A bug? Or am I failing to see possible implications of such a use construct?

1 Like

use functions will have calls-in-place contract since 1.4: https://youtrack.jetbrains.com/issue/KT-35216

1 Like