I think that in Scala 2 normal scoping rules don’t apply to implicits. This is changed in dotty. However myImplicit in MyFoo will shadow myImplicit in MyBar because it has the same name, and in that case there is no ambiguity. In a different scenario where both implicits would have different names, you would have a problem.
scala> trait Implicits { implicit val strImpl = "foo" }
defined trait Implicits
scala> trait Foo extends Implicits
defined trait Foo
scala> trait Bar extends Implicits { val foo = new Foo { implicitly[String] } }
defined trait Bar
scala> trait Baz extends Implicits { implicit val a = 1; val foo = new Foo { implicit val b = 2; println(implicitly[Int]) } }
<console>:13: error: ambiguous implicit values:
both value a in trait Baz of type => Int
and value b of type => Int
match expected type Int
trait Baz extends Implicits { implicit val a = 1; val foo = new Foo { implicit val b = 2; println(implicitly[Int]) } }
^
OK, thanks. Should it affect performance? In other words, if the implicits are introduced only once in the scope is it better or is the shadowing effect insignificant?
I don’t know enough about the implementation to have a definitive answer. But I suspect it doesn’t really affect performance. I guess the compiler just looks at all names that are in the current scope (as part of the first phase of implicit search) and filters out the ones that are implicit and have a compatible type. If a name is shadowed then it is simply no longer in scope, and it will not be found.