Change the treatment of default implementations on interfaces in JVM
compatibility mode. Previously, the IR backend moved the actual
default implementation to the DefaultImpls class, and then bridged to
it from the interface default. The old backend did the reverse, at the
cost of an additional accessor, in order to gain better binary
compatibility properties. See #2612 for discussion.
The accessor needs to call a specific implementation, so must be
performed through an `invokespecial`. We trick the
SyntheticAccessorLowering into doing this for us, by marking the
bridging call as a super call. We do this in want of an explicit
`invokespecial` Ir Node.
InterfaceDefaultCallsPhase previously assumed the old behaviour of the
IR backend (that calls to default implementations, e.g. `foo$default`
should target `DefaultImpls.foo$default`). But now the bridge to
foo$default resides on `DefaultImpls` already, causing that pass to
create a recursive loop. We cut that loop with a simple check.
The JVM IR was too agressive in delegating statically to $DefaultImpls
class.
Consider the following library, compiled separately, and then client,
compiled against that library:
```
//library
interface A { @JvmDefault fun foo() = "A" }
interface Left : A { }
interface Right : A { @JvmDefault override fun foo() = "Right" }
//client
interface C : Left, Right {}
fun main() {
val x = object : C {}
println(x.foo())
}
```
Previously, the IR backend generates an overriding bridge in C, which
calls C$DefaultImpls which calls statically into Right$DefaultImpls.
When then library is recompilerd with an override of foo in Left, the
existing binary of the client continues to run against the recompiled
library erroneously running Right.foo().
The old backend throws an IncompatibleClassChange exception due to
ambiguity of multiple inherited default implementations. kotlinc indeed
rejects the client when recompiled against the new library.
We have no tests constraining this behaviour, but we could conceivably
strap something together in CustomBinaries tests.
We cannot be sure that we won't change behavior of these functions in
some corner cases, so only perform this optimization if the API version
specified by the user is not greater than the compiler's own stdlib
version it was compiled against. This is the same as the similar code in
the old backend in IntrinsicMethods.
Remove sample reference from indexOf(Char) overload: both overloads are on
the same page, and showing the sample for indexOf(String) under indexOf(Char)
is redundant and misleading.
This commit changes XorWowRandom.kt documentation to include a HTTPS link instead of a HTTP link, for security purposes.
This commit also changes the same documentation to reflect the real cycles from the `xorwow` algorithm:
Simple and very fast (125 million/sec), the elements in its cycle of 2^192 − 2^32 easily pass all the tests in Diehard.
Marsaglia, G. 2003. Xorshift RNGs. J. Statis. Soft. 8, 14, p. 5
At last, this commit explicits which part of the code is the implementation of the mentioned algorithm.
Closes KT-35175
Had to edit some bytecodeText tests to account for the fact that JVM_IR
no longer generates explicit initializations for ConstantValue fields,
but NoConstantValueAttributeForNonConstVals is not the default yet.
Before this commit, we used FirAccessorSymbol to emulate synthetic properties.
These symbols were generated in Java use-site scope.
Now, we use synthetic scope instead which is above MemberScopeTowerLevel.
This is more performance-friendly and does not require override matching.
However, accessor symbols should be used in situation when Java accessor
overrides Kotlin property which is broken in this commit
(that's why MapEntry test is corrupted here).
Also, we should not create synthetics for pure Kotlin accessors
(that's why javaAccessorConversion test is corrupted here).
Before this commit, we had two methods to do generally the same synthetic thing.
It's an attempt to keep only one of them.
Accessor symbols are generated in Java use-site member scopes,
at this place we know better whether we are in Java class or not.
However, we have to do this at every use-site level, which is relatively slow.
Also we could encounter problems when accessor function is overridden in Kotlin,
and accessor symbol can still contain reference to Java accessor.
* KT-20357: Add samples for functions related to associate
* KT-20357: Use same fib function for both samples
* KT-20357: Use examples with duplicate keys and simplify examples with primitives
* KT-20357: Use primitive samples for all arrays
* KT-20357: Use String splitting example to better illustrate the use for associate over associateBy with a valueSelector
In case of inline it should be same descriptor (except of fake override), In general case getter could be synthetic accessor and in such case it's not inline