Turin
Turin

Reputation: 2250

What exactly does 'is more specific than' mean in the context of implicits?

So, implicit precedence is based on two factors: one is about the scope of declaration itself having precedence (scope A extending scope/trait B, or scope A being a companion object of a type extended from a type with scope B as its companion object). The other simply mentions that declaration A is more specific than declaration B. Now, when reading it for the first time I had several possible interpretations in mind, especially considering potential parameters (implicit and not) of implicit method and type parameters. Experience seemed to teach me that it means that the type of the returned value by declaration A, after all type inference/tapply, is a subtype of the return type of declaration B. So, this is fine:

  class A
  class B extends A
  implicit val A = new A
  implicit val B = new B
  implicitly[A]

Why this doesn't compile, then?

    implicit class A(val toInt :Int) {
        def ! = (1 /: (2 to toInt))(_ * _)
    }
    implicit class B(i :Int) extends A(i)
    1.!

When this does?

    class A(val toInt :Int) {
        def ! = (1 /: (2 to toInt))(_ * _)
    }
    class B(i :Int) extends A(i)

    implicit val A = { i :Int => new A(i) }
    implicit val B = { i :Int => new B(i) }
    1.!

Is it another case of 'the compiler works in mysterious ways'?

Upvotes: 2

Views: 61

Answers (1)

Guru Stron
Guru Stron

Reputation: 141635

Based on SIP-13 - IMPLICIT CLASSES proposal your declaration:

implicit class A(val toInt :Int) {
    def ! = (1 /: (2 to toInt))(_ * _)
}

Will be transformed to something like:

class A(toInt: Int) {
 ...
}
implicit final def A(toInt: Int): A = new A(toInt);

And your B in its turn will be transformed to something like:

class B(i: Int) extends A(i) {
 ...
}
implicit final def B(i: Int): B = new B(i);

So you are basically declaring 2 implicit conversion methods with the same parameters which are ambiguous. While the last one is not ambiguous due to already mentioned "most specific" rule for implicit parameters resolution.

Upvotes: 3

Related Questions