bug icon indicating copy to clipboard operation
bug copied to clipboard

Unexpected pattern match compile error for generic case class

Open grindvoll opened this issue 7 years ago • 1 comments

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.)

grindvoll avatar Sep 04 '18 08:09 grindvoll

In Dotty, the result is exactly the opposite. Matching on c: Any works, while matching on c: C[_] fails

3.2.1-RC1-bin-20220823-3ad97df-NIGHTLY accepts the c: C[_] version.

SethTisue avatar Aug 25 '22 17:08 SethTisue