I'm wondering if this is a bug or an expected behaviour in Scala 2.13-M5.
Following snippet compiles and outputs "object in package object":
package object test {
implicit val a: TS = new TS("val in package object")
implicit object b extends TS("object in package object")
}
package test {
class TS(override val toString: String)
class Inner {
implicit val f: TS = new TS("val in inner class")
val resolve = implicitly[TS]
}
object Test extends App {
println(new Inner().resolve)
}
}
With commented out third line implicit object b extends TS("object in package object"
there is an ambiguous implicit compile error which is what I would expect in first case as well:
Error:(11, 29) ambiguous implicit values:
both value a in package test of type => test.TS
and value f in class Inner of type => test.TS
match expected type test.TS
val resolve = implicitly[TS]
In your example, a
, b
and f
all seem to be eligible implicit values. As the FAQ says (emphasis mine):
[...] this entails selecting a narrower type or a value defined in a subclass relative to other eligible values
therefore, the object b
is selected, because b.type
is a strict subtype of TS
.
Here is another example that demonstrates the same behavior, but without packages or objects:
case class TS(str: String)
object test {
implicit val a: TS = new TS("val in package object")
// implicit object b extends TS("object in package object")
class MoreSpecial() extends TS("I'm special")
implicit val s: MoreSpecial = new MoreSpecial()
class TS(override val toString: String)
class Inner {
implicit val f: TS = new TS("val in inner class")
val resolve = implicitly[TS]
}
object Test {
def run(): Unit = {
println(new Inner().resolve)
}
}
}
test.Test.run()
it will print "I'm special"
, because the instance of class MoreSpecial
thinks that it's the most specific one, simply because its type MoreSpecial
is a strict subtype of TS
.
Moreover,
b
line, it gives ambiguous implicits error (b: b.type <: TS
conflicts with s: MoreSpecial <: TS
)s
line, it also gives ambiguous implicits error (a: TS
conflicts with f: TS
)s
is commented) XOR (b
is commented)), then it compiles (both b: b.type
and s: MoreSpecial
win over a: TS
and f: TS
)That's all as expected. This holds for 2.12.6, so it doesn't seem specific to 2.13-Mx.