<p dir="auto">When you call a method with a borrowed <code class="notranslate">self</code>, the compiler appears to assume that the borrow of <code class="notranslate">self</code> starts before the other parameters to that method have been evaluated, which seems wrong.  This forces you to create local variables unnecessarily.  Here's an example of code that I think should compile, but doesn't:</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="struct Thingy {
    i:int
}
impl Thingy {
    fn do_something_mutable(&amp;mut self, x: int) {
        // Just assume there's a real reason for self to be mutable here...
        println(format!(&quot;{}&quot;, x));
    }
    fn get_i(&amp;self) -&gt; int { self.i }
}

fn main() {
    let mut o = Thingy{ i: 2 };
    o.do_something_mutable(o.get_i());  // This line should compile, but doesn't
}"><pre class="notranslate"><span class="pl-k">struct</span> <span class="pl-smi">Thingy</span> <span class="pl-kos">{</span>
    <span class="pl-c1">i</span><span class="pl-kos">:</span><span class="pl-smi">int</span>
<span class="pl-kos">}</span>
<span class="pl-k">impl</span> <span class="pl-smi">Thingy</span> <span class="pl-kos">{</span>
    <span class="pl-k">fn</span> <span class="pl-en">do_something_mutable</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span><span class="pl-k">mut</span> <span class="pl-smi">self</span><span class="pl-kos">,</span> <span class="pl-s1">x</span><span class="pl-kos">:</span> <span class="pl-smi">int</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-c">// Just assume there's a real reason for self to be mutable here...</span>
        <span class="pl-en">println</span><span class="pl-kos">(</span><span class="pl-en">format</span><span class="pl-en">!</span><span class="pl-kos">(</span><span class="pl-s">"{}"</span>, x<span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
    <span class="pl-k">fn</span> <span class="pl-en">get_i</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span><span class="pl-smi">self</span><span class="pl-kos">)</span> -&gt; <span class="pl-smi">int</span> <span class="pl-kos">{</span> <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-c1">i</span> <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-k">fn</span> <span class="pl-en">main</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">let</span> <span class="pl-k">mut</span> o = <span class="pl-smi">Thingy</span><span class="pl-kos">{</span> <span class="pl-c1">i</span><span class="pl-kos">:</span> <span class="pl-c1">2</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
    o<span class="pl-kos">.</span><span class="pl-en">do_something_mutable</span><span class="pl-kos">(</span>o<span class="pl-kos">.</span><span class="pl-en">get_i</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>  <span class="pl-c">// This line should compile, but doesn't</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">the error is this:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="lifetime-call-param.rs:13:27: 13:28 error: cannot borrow `o` as immutable because it is also borrowed as mutable
lifetime-call-param.rs:13     o.do_something_mutable(o.get_i());
                                                     ^
lifetime-call-param.rs:13:4: 13:5 note: second borrow of `o` occurs here
lifetime-call-param.rs:13     o.do_something_mutable(o.get_i());
                              ^"><pre class="notranslate"><code class="notranslate">lifetime-call-param.rs:13:27: 13:28 error: cannot borrow `o` as immutable because it is also borrowed as mutable
lifetime-call-param.rs:13     o.do_something_mutable(o.get_i());
                                                     ^
lifetime-call-param.rs:13:4: 13:5 note: second borrow of `o` occurs here
lifetime-call-param.rs:13     o.do_something_mutable(o.get_i());
                              ^
</code></pre></div>
<p dir="auto">If you replace the problematic line with this it compiles and works fine:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="let y = o.get_i();
o.do_something_mutable(y);"><pre class="notranslate"><code class="notranslate">let y = o.get_i();
o.do_something_mutable(y);
</code></pre></div>
<p dir="auto">but isn't that equivalent to the non-compiling version?</p>
<p dir="auto">This is challenging to resolve. I thought I could fit into the new borrow checker, but it is worth addressing separately since there are a number of subtle issues. What this really amounts to is that you need to support borrows where the lifetime of the borrow pointer does not encompass the borrow itself. To handle this safely, we wind up with two loans, the primary one and then a secondary, aliasing loan that tracks the fact that a pointer has been created, even if the memory it points at cannot be dereferenced yet.</p>
<p dir="auto">Part of <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="11256078" data-permission-text="Title is private" data-url="https://github.com/rust-lang/rust/issues/5074" data-hovercard-type="issue" data-hovercard-url="/rust-lang/rust/issues/5074/hovercard" href="https://github.com/rust-lang/rust/issues/5074">#5074</a></p>