Help understanding parameter specialization in Scala

I’m trying to understand the behavior of method dispatch in Scala, especially in the case where the method has multiple specialized arguments.
Can someone explain the difference in the following pieces of code defining locationEq1, locationEq2, and locationEq3? The compiler (at least intelliJ) tells me that the second (locationEq2) is wrong because there is no implementation for areEqual(a:A,b:Any) not defined. So I defined one in locationEq3 which the compiler seems happy about. But to me it seems redundant; certainly a method on Any,Any is already defined. How is it that areEqual(Any,Any) is not already applicable?

  import org.scalactic._
  val epsilon = 1e-3f
  implicit val doubleEq = TolerantNumerics.tolerantDoubleEquality(epsilon)

  implicit val locationEq1 =
    new Equality[Location] {
      def areEqual (a: Location, b: Any): Boolean =
        b match {
          case p: Location => a.lat === p.lat && a.lon === p.lon
          case _ => false
        }
    }
  implicit val locationEq2 =
    new Equality[Location] {
      def areEqual(a: Location, b: Location): Boolean =
        a.lat === b.lat && a.lon === b.lon
    }
  implicit val locationEq3 =
    new Equality[Location] {
      def areEqual(a: Location, b: Any): Boolean =
        false
      def areEqual(a: Location, b: Location): Boolean =
        a.lat === b.lat && a.lon === b.lon
    }

areEqual(a: Location, b: Any) and areEqual(a: Location, b: Location) have the same erasure, meaning that their signatures in the bytecode will be the same, but they don’t have the same meaning in your Scala program. For the first method signature, you can only pass a Location as an argument for parameter a and any value you want as an argument for parameter b. The second signature is more strict; you can only pass in a Location for both parameters.

Thanks Jasper-M for the comment.
They have the same byte code? Is that true even in the case of locationEq3 which has both methods defined? If they have the same byte code, are they both callable?

I’m sorry, I was a little bit mistaken. For trait Foo[A] { def foo(a: A, b: Any): A; def foo(a: A, b: A): A } both methods foo have the same erasure, and it will simply not compile. In your case where the type parameter A is instantiated to Location the compiler will generate specialized methods that don’t have the same erasure.