同じ名前のimplicit defを2つ定義してimportした場合の挙動がScala2.9と2.10で異なる件


言葉では説明しずらいので、とにかくまずは以下のサンプルコードみてください。Scala2.10では、implicit classでもimplicit defでも同じ



package example

object A{
  implicit def foo(self: Int) = new{
    def a = self.toString
  }
}

object B{
  implicit def foo(self: Int) = new {
    def b = self.toString
  }
}

object Main{
  import B._
  import A._

  // Scala 2.10.1 では、以下は両方エラー。2.9では片方だけエラー
  println(1.a)
  println(1.b)
}

Scala2.10では

  • 「名前ぶつかってるよ」というエラーがでる
  • importの順番によって片方がエラーになる

わけでもなく、単にどちらも無効になってコンパイルエラーとしてしかエラーが表示されないってどういうことなの・・・。例えば、上記の例では、どちらかのimplicit class FooをBarなどに変えれば正常にコンパイルできます。これ、普通(外部のライブラリの)implicit classやimplicit defの名前なんて関与したくないというか、基本知らなくていいわけですが、うっかり同じ名前をつけてハマるととてもわかりにくい・・・(というか実際10分くらいハマった)

そして、Scala2.9でimplicit defで同じ名前をつけた場合は「importの順番によって、後からimportしたものが優先されて有効になる」という挙動みたいなのですがががが・・・

  • 2.10においては、これが仕様で、今後も変わる予定ないのか
  • implicit defに関しては、Scala2.9から2.10でのこの変更は意図したものなのか、意図せず変わってしまったのか
  • すでにissueが上がってるのか
  • (実はこれをもっとわかりやすく表示させる)コンパイルオプションなどの何らかの対応策があるのか

など誰か知ってたら教えて下さい・・・。なにかわかったら追記とかします



追記:eed3si9nさんが ML に投稿してくれた
ambiguous implicits resolution fails silently when they are named the same