E223: Cannot Be Included in Capture Set — 캡처 셋에 없는 능력을 참조했어요
E223: Cannot Be Included in Capture Set — 캡처 셋에 없는 능력을 참조했어요
캡처 체킹(capture checking) 중에, 어떤 클래스나 표현식의 캡처 셋에 포함되지 않은 능력(capability) 참조를 그 안에서 사용하면 이 에러가 발생해요.
캡처 체킹은 코드 조각이 사용할 수 있는 능력(가변 참조, I/O 핸들 같은 것들)을 추적합니다. 어떤 클래스가 제한된 캡처 셋을 가질 때 — scala.caps.Pure를 명시적으로 상속하거나, java.lang.Exception 같은 순수 타입을 상속해서 암시적으로 그런 경우 — 그 셋 밖의 능력에 대한 참조는 거부됩니다.
참고: 이 에러는 실험적인 캡처 체킹 기능을 켜야 발생해요.
본문
Example
trait Handle:
val id: String
trait PureParent extends caps.Pure
class Processor(val ctx: Handle^) extends PureParent // error
class ImplicitlyPure(ctx: Handle^) extends java.lang.Exception // error
def test(handle: Handle^) =
new PureParent:
val ctx = handle // error
val id = ctx.id
PureParent는 순수 타입이므로 능력(여기서는 Handle^)에 대한 참조를 가질 수 없어요.
Error
-- [E223] CaptureChecking Error: example.scala:5:20 ----------------------------
5 |class Processor(val ctx: Handle^) extends PureParent // error
| ^
|Reference `Processor.this.ctx` is not included in the allowed capture set {} of the self type of class Processor.
-- [E223] CaptureChecking Error: example.scala:7:21 ----------------------------
7 |class ImplicitlyPure(ctx: Handle^) extends java.lang.Exception // error
| ^
|Reference `ImplicitlyPure.this.ctx` is not included in the allowed capture set {} of the self type of class ImplicitlyPure.
-- [E223] CaptureChecking Error: example.scala:11:8 ----------------------------
11 | val ctx = handle // error
| ^^^^^^^^^^^^^^^^
|Reference `handle` of value ctx is not included in the allowed capture set {} of the self type of anonymous class Object with PureParent {...}.
Solution
순수 타입을 상속하는 클래스는 능력에 대한 참조를 전혀 담을 수 없어요. 코드를 다음과 같이 재구성하면 됩니다 — 두 가지 선택지가 있어요.
trait Handle:
val id: String
trait NonPureParrent
trait PureParent extends NonPureParrent, caps.Pure
class Processor(val ctx: Handle^) extends NonPureParrent
class ImplicitlyPure(ctx: Handle) extends java.lang.Exception
def test(handle: Handle^) =
new PureParent:
val id = handle.id