E192: Unstable Inline Accessor

This warning is emitted when an inline method accesses a non-public member, causing the compiler to generate an unstable accessor.

When an inline method references a private or package-private member, the compiler must generate an accessor method to make that member accessible at the inlining site. This accessor has an automatically generated name that may change between compiler versions, which can break binary compatibility.

This warning requires the -WunstableInlineAccessors compiler flag.


Longer explanation:

Access to a non-public member causes the automatic generation of an accessor. This accessor is not stable, its name may change or it may disappear if not needed in a future version.

To make sure that the inlined code is binary compatible you must make sure that the member is public in the binary API:

  • Option 1: Annotate the member with @publicInBinary
  • Option 2: Make the member public

Example

//> using options -WunstableInlineAccessors
class Example:
  private val secret = 42
  inline def getSecret: Int = secret

Error

-- [E192] Compatibility Warning: example.scala:4:30 ----------------------------
4 |  inline def getSecret: Int = secret
  |                              ^^^^^^
  |Unstable inline accessor Example$$inline$secret was generated in class Example.
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  | Access to non-public value secret causes the automatic generation of an accessor.
  | This accessor is not stable, its name may change or it may disappear
  | if not needed in a future version.
  |
  | To make sure that the inlined code is binary compatible you must make sure that
  | value secret is public in the binary API.
  |  * Option 1: Annotate value secret with @publicInBinary
  |  * Option 2: Make value secret public
  |
  | This change may break binary compatibility if a previous version of this
  | library was compiled with generated accessors. Binary compatibility should
  | be checked using MiMa. If binary compatibility is broken, you should add the
  | old accessor explicitly in the source code. The following code should be
  | added to class Example:
  |   @publicInBinary private[Example] final def Example$$inline$secret: Int = this.secret
   -----------------------------------------------------------------------------

Solution

Use @publicInBinary with package-private access:

//> using options -WunstableInlineAccessors
package foo
import scala.annotation.publicInBinary

class Example:
  @publicInBinary private[foo] val secret = 42
  inline def getSecret: Int = secret

Or make the member public:

//> using options -WunstableInlineAccessors

class Example:
  val secret = 42
  inline def getSecret: Int = secret