-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Closed as not planned
Labels
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.