This is basically a workaround for a slightly different IR generated by
fir2ir vs psi2ir. Simplified, psi2ir generates something like this for
the sample from KT-59218:
TRY type=Unit
try: BLOCK type=Unit
VAR methodHandle [...]
TYPE_OP type=Unit origin=IMPLICIT_COERCION_TO_UNIT
CALL invokeExact [...]
While fir2ir generates the following:
TYPE_OP type=Unit origin=IMPLICIT_COERCION_TO_UNIT
TRY type=Any?
try: BLOCK type=Any?
VAR methodHandle [...]
CALL invokeExact [...]
The lowering relies on the fact that a polymorphic call (`invokeExact`
in this case) is a direct argument to the TYPE_OP, to determine the
correct return type (Unit in this case) to be generated in the bytecode.
The solution here is to push the type coercion "through" all the
block-like structures (`try`, `when`, container expression) so that if
the last statement in the block is a polymorphic call, it gets properly
converted even if the whole block is under a type coercion operation, as
it happens in fir2ir. We achieve that by using the "data" parameter of
the IR transformer: appropriate immediate children of
IrTypeOperatorCall/IrTry/IrWhen/IrContainerExpression get the type that
the expression needs to be coerced to, and all the other expressions
ignore that type and set it to null when transforming their children.
A proper solution would be to ensure fir2ir generates exactly the same
IR as psi2ir (KT-59781), but since PolymorphicSignatureLowering is the
only lowering affected so far, and polymorphic calls occur very rarely,
it seems safe to workaround it in the lowering for now.
#KT-59218 Fixed
This is important for IR lowerings like PolymorphicSignatureLowering
which are very sensitive about the correct types of expressions and
placement of coercions to Unit (KT-59218).
A boolean parameter to `insertImplicitCasts` is not the best solution to
ensure that coercion to Unit is added. The best solution would be to fix
the TODO and generate coercion to the block's type for the last
statement. But that will affect many other places and will need to be
done separately => KT-59781.
Code in IrInterpreter is uncommented to fix the FIR test
`compiler/testData/ir/interpreter/exceptions/tryFinally.kt`; otherwise
evaluation of the function `returnTryFinally` there crashes with
"NoSuchElementException: ArrayDeque is empty". No idea why this test
didn't fail for K1 though, since the created IR is exactly the same.
For some unknown reason this breaks WASM backend with K2, but not with
K1 => KT-59800.
Before this change, it could happen that `when` of type Unit has a
branch whose type is not Unit. This can lead to problems in IR
lowerings, for example PolymorphicSignatureLowering which is very
reliant on the correct types of expressions and placement of coercions
to Unit (KT-59218).
Otherwise, according to the spec, a type will be treated as a final,
which is not correct in many cases.
Later, we can generate final struct types when it's applicable.
#KT-60200 Fixed
In REPL it's possible that builtins will be created several times with
the same symbol table. And since IrBuiltinsPackageFragmentDescriptorImpl
has overridden equals, symbol for external package will be the same for
different descriptors (with same FQN). So we should create IrExternalPackageFragment
here only if it was not created before, on previous compilation