title: Why does adding a second impl prevent deref coercion of the argument?
body: <p>I came across this issue when trying to add the impl <code>Add&lt;char&gt; for String</code> to the standard library. But we can replicate it easily, without operator shenanigans. We start with this:</p>
  
  <pre class="lang-rust prettyprint-override"><code>trait MyAdd&lt;Rhs&gt; {
      fn add(self, rhs: Rhs) -&gt; Self;
  }
  
  impl MyAdd&lt;&amp;str&gt; for String {
      fn add(mut self, rhs: &amp;str) -&gt; Self {
          self.push_str(rhs);
          self
      }
  }
  </code></pre>
  
  <p>Simple enough. With this, the following code compiles:</p>
  
  <pre class="lang-rust prettyprint-override"><code>let a = String::from("a");
  let b = String::from("b");
  MyAdd::add(a, &amp;b);
  </code></pre>
  
  <p>Note that in this case, the second argument expression (<code>&amp;b</code>) has the type <code>&amp;String</code>. It is then deref-coerced into <code>&amp;str</code> and the function call works.</p>
  
  <p><em>However</em>, let's try to add the following impl:</p>
  
  <pre class="lang-rust prettyprint-override"><code>impl MyAdd&lt;char&gt; for String {
      fn add(mut self, rhs: char) -&gt; Self {
          self.push(rhs);
          self
      }
  }
  </code></pre>
  
  <p>(<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2015&amp;gist=eff675766988e8cde50f30a003913ad1" rel="noreferrer">Everything on Playground</a>)</p>
  
  <p>Now the <code>MyAdd::add(a, &amp;b)</code> expression above leads to the following error:</p>
  
  <pre class="lang-none prettyprint-override"><code>error[E0277]: the trait bound `std::string::String: MyAdd&lt;&amp;std::string::String&gt;` is not satisfied
    --&gt; src/main.rs:24:5
     |
  2  |     fn add(self, rhs: Rhs) -&gt; Self;
     |     ------------------------------- required by `MyAdd::add`
  ...
  24 |     MyAdd::add(a, &amp;b);
     |     ^^^^^^^^^^ the trait `MyAdd&lt;&amp;std::string::String&gt;` is not implemented for `std::string::String`
     |
     = help: the following implementations were found:
               &lt;std::string::String as MyAdd&lt;&amp;str&gt;&gt;
               &lt;std::string::String as MyAdd&lt;char&gt;&gt;
  </code></pre>
  
  <p><strong>Why is that?</strong> To me it seems like deref-coercion is only done when there is only one function candidate. But this seems wrong to me. Why would the rules be like that? I tried looking through the specification, but I haven't found anything on argument deref coercion.</p>