Implicit parameters resolution from super trait
implicit, scala
Solution
Call to `aBar` is defined inside `FooTrait`. When this trait compiles, there is no proper implicits in local scope, enclosing class, or parent class. Compiler doesn't try to re-find implicits when you mix in another trait later. So it just uses default implicit from companion object.
You can get value from `SuperFoo` if you override method `go`:
scala> println((new FooTrait with SuperFoo {override def go = {aBar.m}}).go)
from super
You can also redefine you class hierarchy to get your implicit from parent trait:
trait BarHolder {
implicit val superBar: Bar
}
trait FooTrait extends BarHolder {
def aBar(implicit bar:Bar) = bar
def go = { aBar.m }
}
trait DefaultFoo extends BarHolder {
val superBar = implicitly[Bar]
}
trait SuperFoo extends BarHolder {
val superBar = new Bar{ val m = "from super" }
}
and use it this way:
scala> println((new FooTrait with DefaultFoo).go)
from object
scala> println((new FooTrait with SuperFoo).go)
from super
Problem
I am trying use implicit parameters to "inject" a dependency into my classes like this: ``` trait Bar { def m:String } object Bar { implicit val objBar = new Bar{ val m = "from object" } } trait FooTrait { def aBar(implicit bar:Bar) = bar def go = { aBar.m } } ``` Here the compiler supplies the implicit argument to `FooTrait` from the implicit val in `Bar`'s companion object. So doing: ``` scala> println((new FooTrait{}).go) from object ``` Gives me the result I expect. However, if I mix the FooTrait and another trait like: ``` trait SuperFoo { implicit val superBar = new Bar{ val m = "from super" } } ``` The result is the same: ``` scala> println((new FooTrait with SuperFoo).go) from object ``` I thought that the compiler would look in the `SuperFoo` before trying to resolve the implicit argument by checking `Bar`'s companion object. This blog post states: There are very strict rules for which implicit value is to be applied to a implicit parameter. A simple way to think about it is that the "closest" definition will be used. Local scope, enclosing class, parent class, companion object of the desired type. Am I missing something or is this a known limitation of scalas implicit parameters?