Closed as not planned
Description
minimized code
This originated as scala/bug#11860
trait T[A]
object T {
implicit val `default for string`: T[String] = new T[String] {}
}
object Penumbra {
implicit val ours: T[String] = new T[String] {}
}
object Locally {
import Penumbra._
def verify(x: AnyRef) = assert(x eq ours)
def dotty(x: AnyRef) = assert(x eq Penumbra.ours)
implicit val ours: T[String] = new T[String] {}
def test(): Unit = {
val tested = implicitly[T[String]] // fails
//verify(tested)
//verify(implicitly[T[String]]) // fails
dotty(tested)
dotty(implicitly[T[String]])
}
}
object Memberly {
import Penumbra._
def verify(x: AnyRef) = assert(x eq ours)
def dotty(x: AnyRef) = assert(x eq Penumbra.ours)
implicit val ours: T[String] = new T[String] {}
val tested = implicitly[T[String]] // correct
//verify(tested) // OK in scala 2
//verify(implicitly[T[String]]) // fails
dotty(tested)
dotty(implicitly[T[String]])
def test(): Unit = ()
}
object Test extends App {
Locally.test()
Memberly.test()
}
Compilation output
Dotty picks Penumbra.ours
in all cases.
Scala 2 incorrectly decides ours
is shadowed and picks the default in T
, from implicit scope, except for one case, marked OK
, which happens to work as expected.
It's not obvious from the docs whether Dotty intends for the imported Penumbra.ours
to be implicitly available, or whether shadowing nullifies; or which rule picks it; source file order doesn't matter; changing the identifier to avoid shadowing doesn't matter. Moving the import to outer scope does make it pick Locally.ours
, by scope nesting rule, perhaps.
expectation
Locally.ours
and Memberly.ours
should be preferred.