The problem is that JvmRecord has SOURCE retention
Probably, increasing its retention might be a more reliable solution
(or in some other way serializing that the class is a record)
Just checking supertypes seems like a reasonable approximation:
only records kotlin are allowed to extend j.l.Record.
But the relevant diagnostic has been added only since 1.4.30,
so potentially there could have been exist a non-record class with
such supertype compiled by 1.4.20, but this case seems to be ill-formed
and marginal anyway.
For Java classes, it's irrelevant since they don't have member properties
(only synthetic extensions)
^KT-43677 In Progress
If we do, the local variable table will not make sense. As as
example:
```
inline fun foo(getString: () -> String = { "OK" }) {
println(getString())
}
inline fun bar() {
}
fun main() {
bar()
foo()
}
```
leads to the following bytecode:
```
public static final void main();
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
Code:
stack=2, locals=4, args_size=0
0: iconst_0
1: istore_0
2: nop
3: nop
4: iconst_0
5: istore_1
6: nop
7: ldc #53 // String OK
9: astore_2
10: iconst_0
11: istore_3
12: getstatic #30 // Field java/lang/System.out:Ljava/io/PrintStream;
15: aload_2
16: invokevirtual #36 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
19: nop
20: return
LineNumberTable:
line 9: 0
line 13: 2
line 10: 3
line 14: 4
line 15: 6
line 16: 7
line 17: 19
line 11: 20
LocalVariableTable:
Start Length Slot Name Signature
2 1 0 $i$f$bar I
6 14 1 $i$f$foo I
4 16 0 getString$iv Lkotlin/jvm/functions/Function0;
```
The `getString$iv` local should not be there. It has been inlined away.
Leaving it in the local variable table leads to inconsistent locals
info. Local 0 contains an int but we declare a local of type
Function0.
if it is called using parens and not by calling 'invoke' method.
Use underlying type when calling continuation constructor if suspend
function is method inside inline class.
#KT-43505 Fixed
#KT-39437 Fixed
inside 'create' if 'create' overrides 'create' from
BaseContinuationImpl. In other words, unbox the parameter if 'create'
accepts only one parameter.
#KT-43249 Fixed
#KT-43533 Fixed
inside 'invoke' if 'create' does not override 'create' from
BaseContinuationImpl. In other words, when suspend lambda accepts more
than one parameter (including receiver).
Do that only if we do not generate bridge 'invoke' method, since
inline classes are unboxed in the bridge.
Use mangled name for 'create' function in this case inside 'invoke'.
#KT-43249 In progress
#KT-39847 Fixed
#KT-38937 Fixed
1. Use 'x' for each parameter, which is not an inline class, every
possible clash is handled by signature rather than name. This change
makes more API changes binary-compatible. So, the changes are in line
with the vision of inline classes are value classes, like primitives.
2. Take return type into account when mangling a function if the return
type is inline class. Otherwise, boxing bridge will not be generated,
which leads to CCE at runtime.
In the old backend, BindingContextSuppressCache is used (which is now
created explicitly in GenerationState), which looks up `@Suppress`
annotations on elements right before reporting the diagnostic. In JVM
IR, we clear the binding context after psi2ir, so this approach doesn't
work. This change provides another implementation of KotlinSuppressCache
which eagerly precomputes all suppressions on all annotated elements in
all source files at the point of creation of GenerationState (when the
binding context is still full).
#KT-43047 Fixed
- Do not wrap exceptions resulting from generating error expressions
multiple times, as that could lead to stack traces where the identical
code is wrapped many times and is printed in the exception message on
each step, which was difficult to read
- Add element location (file name, line number & position) to the
message, similarly to exceptions from codegen, when catching and
rethrowing exceptions at the top level
The inline class is boxed when we pass it as lambda argument, now we
unbox it. If the underlying type is not Any or Any?, bridge method does
the unboxing.
#KT-32450 Fixed
#KT-39923 Fixed
#KT-32228 Fixed
#KT-40282 Fixed
This helps to reduce peak memory in lowerings/codegen by a lot.
A more robust approach would be to have a separate BindingContext for
each file, and clear each of them after running psi2ir on it. This would
also lower peak memory usage in psi2ir.
Provide a fallback workaround compiler argument
-Xir-do-not-clear-binding-context just in case BindingContext is in fact
used somewhere and it's not caught by tests.