title: Scala: Implicit parameter resolution precedence
body: <p>Suppose we have implicit parameter lookup concerning only local scopes:</p>
  
  <pre><code>trait CanFoo[A] {
    def foos(x: A): String
  }
  
  object Def {
    implicit object ImportIntFoo extends CanFoo[Int] {
      def foos(x: Int) = "ImportIntFoo:" + x.toString
    }
  }
  
  object Main {
    def test(): String = {
      implicit object LocalIntFoo extends CanFoo[Int] {
        def foos(x: Int) = "LocalIntFoo:" + x.toString
      }
      import Def._
  
      foo(1)
    }
  
    def foo[A:CanFoo](x: A): String = implicitly[CanFoo[A]].foos(x)
  }
  </code></pre>
  
  <p>In the above code, <code>LocalIntFoo</code> wins over <code>ImportedIntFoo</code>.
  Could someone explain how it's considered <em>more specific</em> using "the rules of static overloading resolution (§6.26.3)"?</p>
  
  <p><strong>Edit</strong>:</p>
  
  <p>The name binding precedence is a compelling argument, but there are several issues unresolved.
  First, Scala Language Reference says:</p>
  
  <blockquote>
    <p>If there are several eligible arguments which match the implicit parameter’s type, a most specific one will be chosen using the rules of static overloading resolution (§6.26.3).</p>
  </blockquote>
  
  <p>Second, name binding precedence is about resolving a known identifier <code>x</code> to a particular member <code>pkg.A.B.x</code> in case there are several variable/method/object named <code>x</code> in the scope. <code>ImportIntFoo</code> and <code>LocalIntFoo</code> are not named the same.</p>
  
  <p>Third, I can show that name binding precedence <em>alone</em> is not in play as follows:</p>
  
  <pre><code>trait CanFoo[A] {
    def foos(x: A): String
  }
  
  object Def {
    implicit object ImportIntFoo extends CanFoo[Int] {
      def foos(x: Int) = "ImportIntFoo:" + x.toString
    }
  }
  
  object Main {
    def test(): String = {
      implicit object LocalAnyFoo extends CanFoo[Any] {
        def foos(x: Any) = "LocalAnyFoo:" + x.toString
      }
  
      // implicit object LocalIntFoo extends CanFoo[Int] {
      //   def foos(x: Int) = "LocalIntFoo:" + x.toString
      // }
      import Def._
  
      foo(1)
    }
  
    def foo[A:CanFoo](x: A): String = implicitly[CanFoo[A]].foos(x)
  }
  
  println(Main.test)
  </code></pre>
  
  <p>Put this in <code>test.scala</code> and run <code>scala test.scala</code>, and it prints out <code>ImportIntFoo:1</code>.
  This is because static overloading resolution (§6.26.3) says more specific type wins.
  If we are pretending that all eligible implicit values are named the same, <code>LocalAnyFoo</code> should have masked <code>ImportIntFoo</code>.</p>
  
  <p><strong>Related</strong>:</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/5598085/where-does-scala-look-for-implicits">Where does Scala look for implicits?</a></li>
  </ul>
  
  <p>This is a great summary of implicit parameter resolution, but it quotes Josh's nescala presentation instead of the spec. His talk is what motivated me to look into this.</p>
  
  <p><strong>Compiler Implementation</strong></p>
  
  <ul>
  <li><a href="https://github.com/scala/scala/blob/5ee9a14a489c6e56c331914e9db258c0473d4d23/src/compiler/scala/tools/nsc/typechecker/Implicits.scala#L805" rel="nofollow noreferrer"><code>rankImplicits</code></a></li>
  </ul>