This change covers the case where some f/o was generated in common module
and it is referenced in platform code. But signature of this f/o may be
different in different modules because of e.g. actualization of value
parameters with actual typealias
^KT-60850 Fixed
Consider the following example from
`extensionLambdasAndArrow.kt`:
```
val x4: String.() -> String = if (true) {
{ str: String -> "this" }
} else {
{ str: String -> "this" }
}
```
Because of
`coerceFirstParameterToExtensionReceiver`
the given lambdas must be of the type
`String.() -> String`, but because of a bug
they are `String.(String) -> String`. At the
same time, during inference their expected
types are, indeed, calculated correctly as
`String.() -> String`.
^KT-59394 Declined
(no more compiler crashes, #potential-feature)
For annotations defined in Java, IrProperties do not contain initializers in backing fields,
as annotation properties are represented as Java methods.
Therefore, it is not possible to use initializer values as default values for constructor parameters.
However, K2 stores default values in annotation's constructor parameters,
so it is possible to fix this issue if they're properly transfered to the IR
and inspected in JvmAnnotationImplementationTransformer
#KT-47702 Fixed
#KT-47702 tag fixed-in-k2
By ignoring type parameters. Since type parameters in annotations are a
very limited feature, their sole use is to be able to specify them as
KClass argument: annotation class Foo<T: Any>(val bar: KClass<T>).
Since we can encounter type param only as a KClass type argument (and
never as a property type), simple approach of ignoring them works fine.
In that case, since we simply copy property types to synthetic
implementation class, its properties in IR start look like this:
annotation class FooImpl(override val bar: KClass<T of Foo>). This IR
seems to be not completely correct, since FooImpl.bar type contains T of
Foo param, which is out of its scope. However, so far I didn't
encounter any problems with this during testing and after MR discussion
this approach has been considered possible.
#KT-59558 Fixed
#KT-59036 Fixed
In early prototypes of interpreter, it was easier to assume that
all classes from Java can be interpreted and fix something if not.
Check for Java declaration was done by checking that the package name is
starting with "java". But this is actually wrong and can lead to errors
when some code is declared in "java" something package, but is not from
Java stdlib.
#KT-60467 Fixed
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.
This aligns the behavior with K1 and fixes an issue when the default
value was deserialized as FirExpressionStub leading to an exception
in FIR2IR when trying to convert it to an IR expression.
#KT-60120 Fixed
#KT-59610 Fixed
Before this commit, we copied each type parameter during method
enhancement, while not copying the symbol. This led to symbol clashes
in MPP scenarios and various other problems.
Now we create a fully-functional type parameter copy in enhancement
and perform a substitution of old type parameters with new ones
in receiver type, value parameter types, return type,
and type parameter upper bounds.
#KT-59766 Fixed
#KT-59738 Fixed
Earlier we always allowed to interpret `IrGetObjectValue` because
this value is used in const val getter. But now we do a special
check for such getter avoiding visit of `IrGetObjectValue` node.
#KT-59775 Fixed
This fixes an issue with checking for default values in call resolution
(see FirDefaultParametersResolver) where it is expected that the map
only contains a single compatible entry.
#KT-59613 Fixed
... for Kotlin-generated classes which do not correspond to a "class"
from the Kotlin language's point of view. For example, Kotlin lambdas,
file facade classes, multifile class facade/part classes, WhenMappings,
DefaultImpls. They can be distinguished from normal classes by the value
of `KotlinClassHeader.Kind` (which is the same as `Metadata.kind`).
Another theoretical option would be to throw exception at the point
where the `::class` expression is used, if the expression's type on the
left-hand side is a synthetic class. But we can't really do that since
it'll affect performance of most `<expression>::class` expressions.
So, construct a fake synthetic class instead, without any members except
equals/hashCode/toString, and without any non-trivial modifiers. It kind
of contradicts the general idea that kotlin-reflect presents anything
exactly the same as the compiler sees it, but arguably it's worth it to
avoid unexpected exceptions like in KT-41373.
In the newly added test, Java lambda check is muted but it should work
exactly the same as for Kotlin lambdas and other synthetic classes. It's
fixed in a subsequent commit.
#KT-41373 In Progress
kotlin-reflect works correctly already for Kotlin-generated local
classes and anonymous objects, but not for Java ones. This is fixed in a
subsequent commit.
#KT-41373 In Progress
Add some more filters on private/synthetic stuff (which doesn't matter
in practice) to make full and light analysis mode dumps as similar as
possible, so that all existing tests will pass for JVM IR. Unmute some
tests which were failing with the old JVM backend.
Tests on repeatable annotations are muted because in full analysis,
annotations are wrapped into the container (e.g. `@A(1) @A(2)` ->
`@A$Container(A(1), A(2))`), but they are no in the light analysis mode.
So there's always going to be a difference for these tests between full
and light analysis, unless we're going to change behavior of kapt, which
would be a kind of a breaking change.
#KT-58497 Fixed