In case the cast value is used as a receiver to a private method call,
the cast is actually necessary, see KT-48927. Also, this optimization
has backfired once already (see kt48659_identityEqualsWithCastToAny.kt).
It seems that the best way to optimize these casts is not to generate
them in the first place, and/or use bytecode postprocessing.
Apparently the only kind of casts which need to be eliminated are those
which occur on an inline class to its supertype. Otherwise the
unsafe-coerce intrinsic is inserted at the incorrect place, and several
tests fail (uncastInlineClassToAnyAndBack.kt, genericOverride.kt,
classGenericOverride.kt).
#KT-48927 Fixed
- Materialize unit when its value is actually needed.
- Special-case Unit_getInstance return type at codegen. It should be a
proper Unit object instead of a "void"
The difference is how we deal with intermediate fake overrides
E.g., in case
interface A { /* $1 */ fun foo() }
interface B : A {
/* $2 */ fake_override fun foo()
}
interface C : B {
/* $3 */ override fun foo()
}
We've got FIR declarations only for $1 and $3, but we've got
a fake override for $2 in IR.
Previously, override $3 had $1 as its overridden IR symbol, just because
FIR declaration of $3 doesn't know anything about $2.
Now, when generating IR for $2, we save the necessary information
and using it for $3, so it has $2 as overridden.
So, it's consistent with the overridden structure of FE 1.0 and this
structure is necessary prerequisite for proper building of bridges
for special built-ins.
It would allow ConeKotlinType.scope return FirTypeScope
and thus pulling down org.jetbrains.kotlin.fir.scopes.FirScope#processOverriddenFunctions
(See the following commits)
Now FE IR -> BE IR transformation is performed in multiple stages
controller by Fir2IrConverter. Stages are
* files & classes registration
* supertypes & type parameters handling
* functions & properties signature generation
* body generation
After each step we have guarantee (with exception of local classes &
type inference combination, and external symbols) that required symbols
(class/function/property/variable/type parameter)
are already bound to real declarations and have correct parents.
This commit also fixes incorrect parents for local classes
This commit addresses the following issues:
* accessors didn't take into account their property's receiver type,
which caused NoSuchMethod due to signature mismatch. Now the property's
receiver type is passed to Fir2Ir translation of accessors.
* property's parent was not class, e.g., kotlin.collections.indices.
Now the symbol table collects WrappedPropertyDescriptorWithContainerSource
besides WrappedFunctionDescriptorWithContainerSource, so that
facade classes for such properties can be generated before codegen.
* accessor's parent was not class. Now the containerSource of
the property descriptor is passed to accessor descriptor.
Library methods such as 'listOf' are resolved
to have the package fragments as their parents,
but JVM expects their containing file classes as parents.
This fix generates those file classes and
uses them as parent replacements for such library methods.
* fixed NoSuchMethod caused by mismatched signatures of the "invoke" method generated for lambda arguments
* added test cases in invoke.kt for KFunction and anonymous functions
* added a transformer to wrap the last expression in the bodies of lambdas with return
Generate the expression with the original type and then insert
an implicit conversion. That matches the behavior of psi2ir
better and therefore avoids breaking backend assumptions.
In particular, IrGetValue expects the type of the underlying
symbol and the type of the IrGetValue to be the same.