Dynamic dispatch on object, but static dispatch on arguments sometimes

Let me see whether I understand your explanation. Am I correct that there are two methods. One named m(X) and one named m(Y), one has an override but exists in classes X and Y. The other has no override and exists only in class Y. It is as if I had named the two methods mx and my instead of naming them both m.

If I apply my mx/my interpretation to my original code, I indeed get answers which match my test case.

class X {
  def mx(x:X):Int = 1
}
class Y  extends X {
  override def mx(x:X):Int = 2
  def my(y:Y):Int = 3
}

val x:X = new X
val y:Y = new Y
val z:X = new Y
List(
  List(x.mx(x), // 1
       x.mx(y), // 1
       x.mx(z)),  // 1
  List(
    y.mx(x),  // 2
    y.my(y),  // 3 
    y.mx(z)),  // 2
  List(
    z.mx(x), // 2
    z.mx(y), // 2
    z.mx(z))) // 2