Closed
Description
Minimized code
Let's say we have a class and implementation:
trait Person:
def name: String
case class PersonA(name: String) extends Person
case class PersonB(name: String) extends Person
In our macro, we intend to match any kind of Person.name
invocation:
object MatchMac {
inline def apply(inline any: Any): Unit = ${ printMacImpl('any) }
def printMacImpl(any: Expr[Any])(implicit qctx: QuoteContext): Expr[Unit] = {
import qctx.tasty._
any match {
case '{ ($f: Person).name } => println("matched!")
case _ => println("not matched")
}
'{ () }
}
}
Then we create an instance of Person and apply the macro:
MatchMac(PersonA("Joe").name)
Output
The macro will not match the statement:
MatchMac(PersonA("Joe").name)
// not matched
In fact, it will only match if it is directly casted first.
MatchMac(PersonA("Joe").asInstanceOf[Person].name)
// matched!
Expectation
It should match any instance of Person.
MatchMac(PersonA("Joe").name)
// matched!
While theoretically, it is possible to manually cast all instances down to the base type and this will indeed happen with type-hierarchies based on the new 'enum', this is not always possible with existing domain models. In order for quoted matching to be useful, there needs to be some way to make the mechanism match on the the sub-types of an object i.e. be covariant instead of invariant.