Alvaro Carrasco Alvaro Carrasco - 3 months ago 20
Scala Question

Why does pattern match on case object fail when using -Xfuture

The following code compiles fine without

-Xfuture
:

package sandbox

trait M

case object Obj extends M {
def run: Unit = println("RUNNING")
}

object Sandbox extends App {
(Obj: M) match {
case x @ Obj => x.run
}
}


But fails with it:

error: value run is not a member of sandbox.M
case x @ Obj => x.run


Why is it assuming
x
to be of type
M
and not
Obj.type
?

By the way, it appears to compile fine with a
case class
.

Answer

It has to do with which equality you expect in the pattern match.

https://issues.scala-lang.org/browse/SI-1503

scala> trait M
defined trait M

scala> trait X { def x: Int = 42 }
defined trait X

scala> case object O extends X with M
defined object O

scala> (O: M) match { case x @ O => x.x }
res0: Int = 42

scala> :replay -Xfuture
Replaying: trait M
defined trait M

Replaying: trait X { def x: Int = 42 }
defined trait X

Replaying: case object O extends X with M
defined object O

Replaying: (O: M) match { case x @ O => x.x }
<console>:14: error: value x is not a member of M
       (O: M) match { case x @ O => x.x }
                                      ^


scala> (O: M) match { case x: O.type => x.x }
res1: Int = 42

There's an -Xlint warning:

scala> (O: M) match { case x @ O => x.x }
<console>:14: warning: The value matched by O is bound to x, which may be used under the
unsound assumption that it has type O.type, whereas we can only safely
count on it having type M, as the pattern is matched using `==` (see SI-1503).
       (O: M) match { case x @ O => x.x }
                               ^
res0: Int = 42
Comments