Reputation: 1685
I am currently digging in the implicit topic, and got myself stuck with this case :
class A
class B extends A
object A { implicit def b2String(b: B): String = "B" }
object B { implicit def a2String(a: A): String = "A" }
val s: String = new B // This does not compile
I know this is a bit of an edge case, but I wanted to understand it. Shouldn't the compiler pick A's implicit (b2String) ? Or does (as it seems) it stuck to the most specific type's companion object (B) ? Does that mean inherited type's companion object implicits are not inherited ?
Thank you in advance.
EDIT : If A's companion object is deleted, then it compiles and the value of s is "A". So the compiler is able to figure out than an implicit valid for A is also valid for B.
EDIT : If I do the following changes, this also compiles :
class A
class B extends A
object A { implicit def b2String(b: B): Int = 1 }
object B { implicit def a2String(a: A): String = "A" }
val s: String = new B
val i: Int = new B
So companion objects implicits are inherited.
Upvotes: 0
Views: 117
Reputation: 170815
It doesn't compile because there are two available implicits, and by rules in http://scala-lang.org/files/archive/spec/2.11/06-expressions.html#overloading-resolution, they have equal relative weight: b2String
gets 1 over a2String
because it's in the companion object of the derived class, and a2String
gets 1 over b2String
because it's more specific.
Upvotes: 2