The problem is that code in the attached test led to VerifyError at runtime
because the Bar's uninitialized instance created in 'map' was being stored
to the field (leaked from the JVM point of view).
The actual problem was that after repeating visiting of NEW operation
we used to drop the set of already visited copy usages.
For clarification see the comment before 'processUninitializedStores'
#KT-15016 Fixed
ContinuationInterceptor companion object is named Key
CoroutineContext.Element property for key is named just key
AbstractCoroutineContextElement implements all of CoroutineContext.Element, including key
The problem appears for tail-optimized suspend functions,
we erroneously assumed that when/if/try expressions in tail-call
position have simple types like `I` while actually, they can return SUSPENDED
object, i.e. must have `java/lang/Object` as return type.
But this only concerns branching operations in tail-call position,
so we have to make an additional analysis for remembering whether
a given expression is in a tail-call position.
Also, it's important here that we now assume
the return type of the current function as `java/lang/Object`
that is necessary to avoid wrong checkcasts.
#KT-15364 Fixed
Revert changes for "tolerant to uninitialized values" in OptimizationBasicInterpreter:
this approach doesn't converge for some specific cases where local variable is reused
(e.g., in several inlined functions - see https://youtrack.jetbrains.com/issue/KT-15112).
Instead, treat fake always-false conditional jump in the beginning of the post-condition loop as a "reference point" for stack on loop break / continue.
This requires an extra abstraction layer in FixStackAnalyzer, since we can't perform fine-grain manipulations on Frames
(such as "combine frame C from local variables of frame A and stack of frame B").
NB additional NOPs will be generated for post-condition loops.
Should make a separate bytecode postprocessing pass to get rid of unnecessary NOPs
(several YT issues for perceived quality of the generated bytecode are about such NOPs).
For special calls (when-expressions, if-expressions, etc.), do not attempt to
get type of the argument expression, which is the block with the callable
reference, instead get type of the callable reference itself. The difference
matters because for block expressions, a new lexical scope is created for each
getTypeInfo (see ExpressionTypingServices.getBlockReturnedType), and we do not
support rewrites of this value in the binding trace
#KT-12044 Fixed