title: Magnet pattern and overloaded methods
body: <p>There is a significant difference in how Scala resolves implicit conversions from "Magnet Pattern" for non-overloaded and overloaded methods.</p>
  
  <p>Suppose there is a trait <code>Apply</code> (a variation of a "Magnet Pattern") implemented as follows.</p>
  
  <pre><code>trait Apply[A] {
   def apply(): A
  }
  object Apply {
    implicit def fromLazyVal[A](v: =&gt; A): Apply[A] = new Apply[A] {
      def apply(): A = v
    }
  }
  </code></pre>
  
  <p>Now we create a trait <code>Foo</code> that has a single <code>apply</code> taking an instance of <code>Apply</code> so we can pass it any value of arbitrary type <code>A</code> since there an implicit conversion from <code>A =&gt; Apply[A]</code>.</p>
  
  <pre><code>trait Foo[A] {
    def apply(a: Apply[A]): A = a()
  }
  </code></pre>
  
  <p>We can make sure it works as expected using REPL and <a href="https://gist.github.com/mpilquist/4ed3196e9ee4543c1847">this workaround to de-sugar Scala code</a>.</p>
  
  <pre><code>scala&gt; val foo = new Foo[String]{}
  foo: Foo[String] = $anon$1@3a248e6a
  
  scala&gt; showCode(reify { foo { "foo" } }.tree)
  res9: String =    
  $line21$read.foo.apply(
    $read.INSTANCE.Apply.fromLazyVal("foo")
  )
  </code></pre>
  
  <p>This works great, but suppose we pass a <em>complex expression</em> (with <code>;</code>) to the <code>apply</code> method.</p>
  
  <pre><code>scala&gt; val foo = new Foo[Int]{}
  foo: Foo[Int] = $anon$1@5645b124
  
  scala&gt; var i = 0
  i: Int = 0
  
  scala&gt; showCode(reify { foo { i = i + 1; i } }.tree)
  res10: String =
  $line23$read.foo.apply({
    $line24$read.`i_=`($line24$read.i.+(1));
    $read.INSTANCE.Apply.fromLazyVal($line24$read.i)
  })
  </code></pre>
  
  <p>As we can see, an implicit conversion has been applied only on the last part of the complex expression (i.e., <code>i</code>), not to the whole expression. So, <code>i = i + 1</code> was strictly evaluated at the moment we pass it to an <code>apply</code> method, which is not what we've been expecting.</p>
  
  <p>Good (or bad) news. We can make <code>scalac</code> to use the whole expression in the implicit conversion. So <code>i = i + 1</code> will be evaluated lazily as expected. To do so we (surprize, surprize!) we add an overload method <code>Foo.apply</code> that takes any type, but not <code>Apply</code>.</p>
  
  <pre><code>trait Foo[A] {
    def apply(a: Apply[A]): A = a()
    def apply(s: Symbol): Foo[A] = this
  }
  </code></pre>
  
  <p>And then.</p>
  
  <pre><code>scala&gt; var i = 0
  i: Int = 0
  
  scala&gt; val foo = new Foo[Int]{}
  foo: Foo[Int] = $anon$1@3ff00018
  
  scala&gt; showCode(reify { foo { i = i + 1; i } }.tree)
  res11: String =
  $line28$read.foo.apply($read.INSTANCE.Apply.fromLazyVal({
    $line27$read.`i_=`($line27$read.i.+(1));
    $line27$read.i
  }))
  </code></pre>
  
  <p>As we can see, the entire expression <code>i = i + 1; i</code> made it under the implicit conversion as expected.</p>
  
  <p>So my question is why is that? Why the scope of which an implicit conversion is applied depends on the fact whether or not there is an overloaded method in the class.</p>