Description
Compiler version
3.0, 3.1, 3.2, 3.3
Inline accessors
Whenever we refer to a definition that is not public in an inline definition, we generate an inline accessor to access that definition from where the code is inlined.
final class C:
private def a: Int = 2
inline def b: Int = a + C.d
object C:
private[C] val d: Int = 4
is transformed into something like
final class C:
private def a: Int = 2
def inline$a = a
def inline$d = C.d
inline def b: Int = inline$a + inline$d
object C:
private[C] val d: Int = 4
Note that the accessors are added to the class using the private definition. This can lead to duplication of accessors.
Issue 1: Changing any definition from private to public is a binary incompatible change
object C:
- private def a: Int = 2
+ def a: Int = 2
inline def b: Int = a
This change would remove the need to generate C$$inline$a
because a
is publicly accessible. But any compiled code that inlined b
before this change refers to C$$inline$a
. This code can be located in different libraries, and we might be unable to recompile it with the new inline definition.
Issue 2: Changing the implementation of an inline definition can be a binary incompatible change
object C:
private def a: Int = 2
- inline def b: Int = a
+ inline def b: Int = 3
This change would remove the need to generate C$$inline$a
because we never inline a
. But any compiled code that inlined b
before this change refers to C$$inline$a
. This code can be located in different libraries, and we might be unable to recompile it with the new inline definition.
Issue 3: Removing final
from a class is a binary incompatible change
- final class C:
+ class C:
private def a: Int = 2
inline def b: Int = a
If the class is final a
will get the accessor inline$a
but if it is not final it gets the accessor C$$inline$a
.