The light analysis test data is not needed anymore cause the light analysis result is now automatically checked against the one from the full analysis.
Inline lambda could capture reified parameter of containing inline function ('a' function)
when it is inlined in another one.
If it's inlined in any anonymous object we should track it and
add reification marker to such anonymous object instance creation
to rewrite it on inlining bytecode of 'a' function.
#KT-15997 Fixed
Allow kotlin.jvm.internal.Intrinsics#areEqual for boxed values.
Rewrite to primitive equality.
NB we can't do that for Float and Double, because java.lang.Float#equals
and java.lang.Double#equals behave differently from primitive equality comparisons.
CHECKCAST is redundant if the corresponding static type exactly matches the target type.
CHECKCAST instructions to-be-reified should not be eliminated.
KT-14811 Unnecessary checkcast generated in parameterized functions
KT-14963 unnecessary checkcast java/lang/Object
KT-16194 Code with unnecessary safe call contains redundant boxing/unboxing for primitive values
KT-12839 Two null checks are generated when manually null checking platform type
Recognize some additional cases of trivial null checks and trivial instance-of checks.
A variable is "checked for null", if it is:
- a function parameter checked with 'INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull'
- checked for nullability with 'IFNULL/IFNONNULL'
- checked for nullability with 'INSTANCEOF'
(if objectref is instance-of T, then objectref is non-null)
Before analyzing nullability, introduce synthetic assumptions for execution branches
where a variable is guaranteed to be null or not null. For example, the following bytecode:
ALOAD 1 // Ljava/lang/String;
IFNULL L
<non-null branch>
L:
<null branch>
is transformed to
ALOAD 1
IFNULL L1
NEW java/lang/String
ASTORE 1 // tells analyzer that variable 1 is non-null
<non-null branch>
L:
<null branch>
L1:
ACONST_NULL
ASTORE 1 // tells analyzer that variable 1 is null
GOTO L
After the analysis is performed on a preprocessed method,
remember the results for "interesting" instructions
and revert the preprocessing transformations.
After that, perform bytecode transformations as usual.
Do not transform INSTANCEOF to-be-reified, because reification at call site
can introduce null checks. E.g.,
inline fun <reified T> isNullable() = null is T
...
assert(isNullable<String?>())
This patch mutes the following test categories:
* Tests with java dependencies (System class,
java stdlib, jvm-oriented annotations etc).
* Coroutines tests.
* Reflection tests.
* Tests with an inheritance from the standard
collections.
The problem is very subtle (see the test): when generating a signature
for an object literal we also were mapping its super-class
(a type alias here).
Although we did unwrap its underlying constructor to map it properly
we did too late (after obtaining value parameters from the type alias constructor descriptor).
Another problem is that TypeAliasConstructorDescriptor.getOriginal
in the case does return itself, while it's expected to return
unsubstituted version
Note: everything works for common calls for such constructors
because they mapped through mapCallableMethod which contains
another custom unwrapping of type alias constructors
#KT-16555 Fixed
See how we translate raw types to Kotlin model:
RawType(A) = A<ErasedUpperBound(T1), ...>
ErasedUpperBound(T : G<t>) = G<*> // UpperBound(T) is a type G<t> with arguments
ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments
ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F
Stack overflow happens with the following classes:
class A<X extends B> // NB: raw type B in upper bound
class B<Y extends A> // NB: raw type A in upper bound
when calculating raw type for A, we start calculate ErasedUpperBound(Y),
thus starting calculating raw type for B => ErasedUpperBound(X) => RawType(A),
so we have SOE here.
The problem is that we calculating the arguments for these raw types eagerly,
while from the definition of ErasedUpperBound(Y) we only need a type constructor
of raw type B (and the number of parameters), we don't use its arguments.
The solution is to make arguments calculating for raw types lazy
#KT-16528 Fixed
(it can be different from 'getContainingDeclaration()' in case of type alias constructor).
KT-15109 Subclass from a type alias with named parameter in constructor will produce compiler exception
KT-15192 Compiler crashes on certain companion objects: "Error generating constructors of class Companion with kind IMPLEMENTATION"
1. Analyze method node with fake jumps for loops to make sure that
all instructions reachable only through break/continue jumps are processed.
2. Fix stack for break/continue jumps.
3. Drop fake jumps for loops, analyze method node again.
4. Fix stack for try/catch and beforeInline.
Before this change such wrapping happened only during coercion,
i.e. when a call-site expected a KClass instance.
But when call-site expects Any, for example, no wrapping happened,
and raw j.l.Class instance was left on stack.
The solution is to put wrapping code closer to generation of annotation's
method call itself to guarantee that necessary wrapping will happen.
#KT-9453 Fixed
Finnaly markers are used only for non-local return processing and are removed after inlining to non-inline functions, same deletion should be performed on inlining to anonymous objects
#KT-16532 Fixed
The problem was that he number of mask parameters for defaults when
generating methods declaration was being calculated upon resulting signature
(with additional parameters: extension receivers, enum name/ordinal),
while on call-sites the masks number was calculated by the arguments number
in resolved call, i.e. by the number of real value parameters.
And because of the additional synthetic parameters (like enum.ordinal) these
two numbers could be different.
The solution is just to use value parameters number in both places.
Note, that we only count value parameters from the original sourse
declaration, ignoring synthetic ones generated by backend (e.g.
Continuation for suspend functions)
#KT-14565 Fixed
See the issue and the test. The problem was that when generating
call to `foo` method in member scope of `AT<*>` its resulting descriptor
after substitution and approximation was: fun foo(x: Nothing..Array<out Nothing>).
This signature is correct, but when using this parameter type
for generating a vararg argument the assertion is violated that
the type of the argument must be an array
(by default we're using lower flexible bound everywhere)
The solution is using upper bound for flexible types that should
always have a form of Array<out T> for varargs (even for such corner cases)
both for Kotlin and Java declarations.
#KT-14607 Fixed
The problem was that when obtaining char from the wrapper,
codegen used int as expected type that led
to a ClassCastException: java.lang.Character cannot be cast to java.lang.Number
The solution is using coercion to chars, it's still correct,
because of implicit widening coercion in JVM from C to I
#KT-15105 Fixed
The problem was that in `Function<T>.apply(T)` T is now not-platform,
so when checking if not-null assertion is needed for parameter in SAM,
it's defined by the upper bounds of T that is a platform (Any..Any?),
and while it's definitely not marked as nullable it's still nullable
in a sense that it can contain null as a value.
So the solution is obvious
#KT-16413 Fixed
The problem was that anonymous classes wasn't regenerated
although they capture another anonymous class that is a subject
for regeneration
#KT-8689 Fixed