E219: Cannot Instantiate Quoted Type Variable — quoted 패턴의 타입 변수는 new로 만들 수 없어요
E219: Cannot Instantiate Quoted Type Variable — quoted 패턴의 타입 변수는 new로 만들 수 없어요
quoted 패턴 안에서 타입 변수를 new 뒤에 사용하면 이 에러가 발생해요. 매크로에 쓰이는 quoted 패턴에서는 소문자 타입 이름이 "아무 타입이나 맞는" 타입 변수로 취급되는데, 이 타입 변수는 컴파일 타임에 어떤 생성자를 호출해야 할지 알 수 없어서 new로 인스턴스화할 수 없어요.
실제 클래스를 가리키려던 거라면 이름을 백틱으로 감싸서 이스케이프하면 되고, 패턴 매칭에서 인스턴스를 직접 만들어야 한다면 더 저수준인 quotes.reflect API를 사용하는 걸 고려해 보세요.
본문
Example
import scala.quoted.*
def inspectMacro(x: Expr[Any])(using Quotes): Expr[String] =
x match
case '{ new t($arg) } => '{ "found new with arg" }
case _ => '{ "other" }
Error
-- [E219] Staging Issue Error: example.scala:5:16 ------------------------------
5 | case '{ new t($arg) } => '{ "found new with arg" }
| ^
|Quoted pattern type variable `t` cannot be instantiated.
|If you meant to refer to a class named `t`, wrap it in backticks.
|If you meant to introduce a binding, this is not allowed after `new`. You might
|want to use the lower-level `quotes.reflect` API instead.
|Read more about type variables in quoted pattern in the Scala documentation:
|https://docs.scala-lang.org/scala3/guides/macros/quotes.html#type-variables-in-quoted-patterns
|
Solution
특정 클래스를 매칭하고 싶다면 백틱으로 이름을 이스케이프하면 됩니다.
import scala.quoted.*
class myClass(val value: Int)
def inspectMacro(x: Expr[Any])(using Quotes): Expr[String] =
x match
case '{ new `myClass`($arg) } => '{ "found myClass" }
case _ => '{ "other" }
new가 얽힌 더 복잡한 패턴 매칭은 quotes.reflect API를 사용해 보세요.
import scala.quoted.*
def inspectMacro(x: Expr[Any])(using Quotes): Expr[String] =
import quotes.reflect.*
x.asTerm match
case Apply(Select(New(tpt), _), args) => '{ "found new expression" }
case _ => '{ "other" }