There are many complications with the current design of passing data
from within in-place lambdas to surrounding code. Solving these
complications will involve more time to investigation than is available
within the K2 release. So we are disabling passing type statement
information from lambdas for the time being until more time can be
devoted to a more complete solution.
^KT-60958 Fixed
^KT-63530 Fixed
In theory, forking persistent flows should be cheap because of object
reuse, so the proposal here is to start from scratch and prove
redundancy of forks on a case-by-case basis. Something something better
safe than sorry.
^KT-28333 tag fixed-in-k2
^KT-28489 tag fixed-in-k2
var p: String? = something
if (p != null) {
foo(
run { p = null; n() },
// This lambda executes strictly after the one above by CFG,
// but data flow for type inference comes from before the call
// so p would get smartcasted if not forbidden.
run { p.length; 123 }
)
}
Consider a function `run2` that has 2 lambda arguments called in place.
We don't know the order in which they're called, so here:
var x: Any? = something
run2(
{ x = null },
{ x as String },
)
// <--
it's not correct to simply `&&` the statements together, as that would
produce `x is Nothing? && x is String && x is Any?`. Instead, statements
should be grouped by assignment first, and different groups are `||`-ed.
This means in the above example we now get `x is Nothing? || (x is Any?
&& x is String)` == `x is String?`.
For example:
foo(
// `if` joins A & B
if (condition)
run { ... } // A
else
run { ... }, // B
run { ... } // C
) // `foo` unifies `A & B` and `C`, so if it is not resolved itself,
// further `if`s, `when`s, safe calls outside it, etc. continue
// building the correct type predicate until the next completed
// call.
^KT-44512 Fixed