E195: Phantom Symbol Not Value
E195: Phantom Symbol Not Value
이 에러는 컴파일러가 만들어 낸 팬텀(phantom) 심볼을 독립된 값으로 사용하려고 할 때 발생해요. 팬텀 심볼은 여러 기능을 위해 컴파일러가 합성해 만든 항목이지만, 실제 값으로는 쓸 수 없어요.
본문
이 에러는 다음과 같은 경우에 발생해요.
- Constructor proxies: 케이스 클래스가 아닌 클래스의 팩토리 메서드를 나타내는 심볼 (3.3.1부터)
- Context bound companions: 컨텍스트 바운드의 증인(witness)을 나타내는 심볼 (3.5.0부터)
- Dummy capture parameters: 실험적 캡처 체킹(capture checking)에서 캡처 파라미터에 대한 참조를 나타내는 심볼 (3.7.2부터)
참고: 이 에러 코드는 여러 메시지 클래스에서 사용되므로, 정확한 메시지는 문맥에 따라 달라져요.
예시 (Example)
아래 예시는 더미 캡처 파라미터를 값으로 잘못 사용한 경우를 보여줘요. 실험적 캡처 체킹 기능을 사용할 때 발생해요.
import language.experimental.captureChecking
class A:
type C^
def example(a: A): a.C = a.C
여기서 C^는 캡처 파라미터 타입을 선언하고, 컴파일러는 캡처 집합에서 이를 참조할 수 있도록 합성 용어(term) C를 만들어요. 하지만 이 용어는 실제 값으로 사용될 수는 없어요.
에러 (Error)
-- [E195] Type Error: example.scala:6:27 ---------------------------------------
6 |def example(a: A): a.C = a.C
| ^^^
| dummy term capture parameter value C cannot be used as a value
|-----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| A term capture parameter is a symbol made up by the compiler to represent a reference
| to a real capture parameter in capture sets. For instance, in
|
| class A:
| type C^
|
| there is just a type `A` declared but not a value `A`. Nevertheless, one can write
| the selection `(a: A).C` and use a a value, which works because the compiler created a
| term capture parameter for `C`. However, these term capture parameters are not real values,
| they can only be referred in capture sets.
-----------------------------------------------------------------------------
해결 방법 (Solution)
팬텀 심볼 대신 실제로 선언된 멤버를 사용해요.
import language.experimental.captureChecking
class A:
type C^
val getC: C = ???
def example(a: A): a.C = a.getC