This is a follow-up question of:
In Scala 3: Why runtime pattern matching can't work reliably on duck type using JVM reflection?
I'm trying to create a pattern matching implementation in Scala that is more resilient to type erasure. It should still rely on only JVM reflection on class but can degrade smoothly to alternatives in case of a runtime sanity check or class cast error.
The signature of my implementation looks like this:
@unchecked
case class Match[T](self: T) {
def apply[R](
@unchecked cases: PartialFunction[T, R]*
): R = ???
}
When testing it on a case that involves type erasure:
trait H {
type Unknown <: String
Match("abc": Serializable).apply(
{ case v: Unknown => 1 },
{ case v: Any => 2 }
)
}
I still got the warnings:
[Warn] /xxx.scala:20:19: abstract type pattern Has.this.Unknown is unchecked since it is eliminated by erasure
[Warn] /xxx.scala:20:16: The outer reference in this type test cannot be checked at run time.
It appears that @unchecked annotation has no effect on suppressing compiler message. This effectively rules out possibility to use partial function in my definition.
How can this warning be suppressed?
Well, you just put @unchecked
in wrong places. It's for annotating types (making a type AnnotatedType internally). Try to annotate the type in type pattern. Usage example is in the scaladoc of @unchecked
and in Scala spec.
case class Match[T](self: T) {
def apply[R](
cases: PartialFunction[T, R]*
): R = ???
}
trait H {
type Unknown <: String
Match("abc": Serializable).apply(
{ case v: Unknown @unchecked => 1 },
{ case v: Any => 2 }
)
}
Scaladoc: https://www.scala-lang.org/api/2.13.10/scala/unchecked.html
Scala spec: https://www.scala-lang.org/files/archive/spec/2.13/11-annotations.html#scala-compiler-annotations
What is correct syntax for @unchecked in a fold operation
Scala: recursively pattern match a heterogeneous list, obtaining the correct type of each element