Open
Description
The following code fails to compile for scala 2.12.6 and 2.13.0-M5:
trait Is[A]
case object IsInt extends Is[Int]
case object IsString extends Is[String]
case class C[A](is: Is[A], value: A)
val c: Any = C(IsString, "name") // Note: val c: C[_] works!
c match {
case C(IsInt, i) if i < 10 => println(s"An Int less than 10")
case C(IsString, s) => println(s"A String with length ${s.length}")
case _ => println("No match")
}
The compiler reports:
[error] C:\dev\scala\213test\src\main\scala\Hello.scala:11:12: pattern type is incompatible with expected type;
[error] found : IsInt.type
[error] required: Is[Any]
[error] Note: Int <: Any (and IsInt.type <: Is[Int]), but trait Is is invariant in type A.
[error] You may wish to define A as +A instead. (SLS 4.5)
[error] case C(IsInt, i) if i < 10 => println(s"An Int less than 10")
[error] ^
[error] C:\dev\scala\213test\src\main\scala\Hello.scala:11:27: value < is not a member of Any
[error] case C(IsInt, i) if i < 10 => println(s"An Int less than 10")
[error] ^
[error] C:\dev\scala\213test\src\main\scala\Hello.scala:12:12: pattern type is incompatible with expected type;
[error] found : IsString.type
[error] required: Is[Any]
[error] Note: String <: Any (and IsString.type <: Is[String]), but trait Is is invariant in type A.
[error] You may wish to define A as +A instead. (SLS 4.5)
[error] case C(IsString, s) => println(s"A String with length ${s.length}")
[error] ^
[error] C:\dev\scala\213test\src\main\scala\Hello.scala:12:63: value length is not a member of Any
[error] case C(IsString, s) => println(s"A String with length ${s.length}")
[error] ^
[error] four errors found
The code compiles by refining the type c
from val c: Any
to val c: C[_]
.
(In Dotty, the result is exactly the opposite. Matching on c: Any
works, while matching on c: C[_]
fails.)