Reputation: 1951
Here is a simplification of what I encountered. This compiles:
trait A { implicit val x = 1 }
trait B extends A { val y = implicitly[Int] }
While this don't (could not find implicit value):
trait B extends A { val y = implicitly[Int] }
trait A { implicit val x = 1 }
I tried to make my intentions clear by specifying a self-type: trait A { this: B => ... }
, but to no avail.
How do I deal with this kind of dependencies without worrying about how my code is laid out?
Upvotes: 6
Views: 172
Reputation: 29528
You need to declare the type explicitly, at least for the latter one
trait B extends A { val y = implicitly[Int] }
trait A { implicit val x : Int = 1 }
The rules for implicit visibility is different whether its type is declared explicitely or not. If it is not, the implicit is available (as an implicit) only after the point of declaration.
The reason is that type inference may become too difficult if the type was not declared (as in recursive routine). In many cases, inference would be easy (as in your code) but the spec has to be clear cut.
Upvotes: 11