Hi,
There have been a few 2.10 [implicits][2] [discussions][2] already,
but I'm seeing them popping up around me,
so let me bring it up here. Sorry if it's been reported already.
### ambiguous reference in Scala 2.9.2
Let's first see how ambiguous reference is reported in 2.9.2.
scala> :paste
// Entering paste mode (ctrl-D to finish)
object X {
implicit def foo = 1
}
object Y {
implicit def foo = 2
}
object Z {
import X._
import Y._
println(foo)
}
// Exiting paste mode, now interpreting.
<console>:18: error: reference to foo is ambiguous;
it is imported twice in the same scope by
import Y._
and import X._
println(foo)
^
### ambiguous implicit reference in Scala 2.9.2
Next we implicitly use foo.
scala> :paste
// Entering paste mode (ctrl-D to finish)
object X {
implicit def foo = 1
}
object Y {
implicit def foo = 2
}
object Z {
import X._
import Y._
println(implicitly[Int])
}
// Exiting paste mode, now interpreting.
defined module X
defined module Y
defined module Z
scala> Z
2
res0: Z.type = Z$@8c96c01
Magically it works.
### ambiguous implicit reference in Scala 2.10.1
Now let's run this on 2.10.1.
scala> :paste
// Entering paste mode (ctrl-D to finish)
object X {
implicit def foo = 1
}
object Y {
implicit def foo = 2
}
object Z {
import X._
import Y._
println(implicitly[Int])
}
// Exiting paste mode, now interpreting.
<console>:19: error: could not find implicit value for parameter e: Int
println(implicitly[Int])
^
When the implicit defs are named the same, the implicit resolution fails siliently.
### ambiguous implicit reference in Scala 2.10.1 with different name
To prove this point, let me rename one of the foos to bar.
scala> :paste
// Entering paste mode (ctrl-D to finish)
object X {
implicit def foo = 1
}
object Y {
implicit def bar = 2
}
object Z {
import X._
import Y._
// println(foo)
println(implicitly[Int])
}
// Exiting paste mode, now interpreting.
<console>:19: error: ambiguous implicit values:
both method foo in object X of type => Int
and method bar in object Y of type => Int
match expected type Int
println(implicitly[Int])
^
### what I would expect for foo and foo situation
I think it's a bug that the compiler doesn't make it clear
that X.foo and Y.foo are ambiguous, and I'd expect something like:
<console>:19: error: ambiguous implicit values:
both method foo in object X of type => Int
and method foo in object Y of type => Int
match expected type Int
println(implicitly[Int])
^
Thanks to Jason, I am aware of -Xlog-implicits, but I shouldn't have to
use it to find out ambiguous imports.
The problem is that it's not clear where the conflicting implicits
are coming from especially from the library users point of view.
It's sometimes not even clear that the compile error is due to implicit
conversion. It'd say something like "required: treehugger.forest.TermName."
Thanks,
-eugene
### notes
- [xuwei_k blogged about this topic in Japanese][3]
- [treehugger.scala stopped working for 2.10][4]
- [Scala compiler error when using Scalaz7 and Json4s][5] (possibly related?)