docs/inlining/examples/accessing-private.md
Sometimes, inline functions have more priveliges, than their callsite has.
class A {
private fun bar() { println("bar")}
inline internal fun foo() = bar()
}
fun main() {
A().foo()
}
This code is compilable, and effectively equivalent to calling bar() in main.
But bar() is a private function and can't be called in main().
As inlining happens after klib linking, there is no issue with that.
For methods, synthetic accessors are generated.
For example, class A from above is generated to
public final class A {
public A();
private final void bar();
public final void foo$main();
public static final void access$bar(A);
}
And this access$bar(A) method is called instead of bar inside inline functions.
Accessing classes is more complex. They are just accessed as is. Which works in simple cases, but for example
// other.kt
package other
class A {
private class B public constructor() {
fun bar() { println("bar")}
}
private fun produce() : Any = B()
private fun consume(b: B) { b.bar() }
inline internal fun foo() {
val x = produce() as B
consume(x)
}
}
// main.kt
fun main() {
other.A().foo()
}
fails with IllegalAccessError.
It is unclear if it should be considered as a bug, and deprecated, or it is intended behaviour.
Probably, we can use this approach in all backends and move it to fir2ir phase.