E192: Unstable Inline Accessor — 불안정한 inline 접근자

E192: Unstable Inline Accessor — 불안정한 inline 접근자

inline 메서드가 non-public 멤버에 접근해서 컴파일러가 불안정한 접근자(accessor)를 생성하도록 할 때 발생하는 경고예요.

출처: Scala 3 Reference

본문

inline 메서드가 private 또는 패키지-프라이빗 멤버를 참조하면, 컴파일러는 인라인 지점에서 그 멤버에 접근할 수 있게 하기 위해 접근자 메서드를 생성해야 해요. 이 접근자는 자동 생성된 이름을 가지는데, 컴파일러 버전에 따라 바뀔 수 있어서 바이너리 호환성을 깨뜨릴 수 있어요.

이 경고는 -WunstableInlineAccessors 컴파일러 플래그가 필요해요.

좀 더 자세한 설명 (Longer explanation)

non-public 멤버에 대한 접근은 접근자의 자동 생성을 유발해요. 이 접근자는 불안정해서, 이름이 바뀌거나 미래 버전에서 필요 없어지면 사라질 수도 있어요.

인라인된 코드가 바이너리 호환되도록 하려면, 해당 멤버가 바이너리 API에서 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)

패키지-프라이빗 접근과 함께 @publicInBinary를 사용하세요:

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

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

아니면 멤버를 public으로 만들세요:

//> using options -WunstableInlineAccessors

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

더 알아보기

inline 메서드가 접근하는 non-public 멤버는 컴파일러가 생성하는 접근자를 통해 노출돼요. @publicInBinary를 붙이거나 멤버를 public으로 만들어 바이너리 호환성을 지키세요.