× {{alert.msg}} Never ask again
Get notified about new tutorials RECEIVE NEW TUTORIALS

Mutable borrow conflict from unrolled loop

Chris Morgan
Jul 15, 2015
<p>It is not possible in Rust to have a reference to something in the same structure.</p> <p>Think about it:</p> <pre><code>struct Line&lt;'a&gt; { text: Box&lt;String&gt;, column: &amp;'a str, } </code></pre> <p>What is <code>'a</code> intended to be? The lifetime of the <code>text</code> field (by the way, the <code>Box</code> wrapping around a <code>String</code> is completely superfluous). You thus can’t express the type until it already exists.</p> <p>If such a reference <em>were</em> permitted, you’d run into problems like this:</p> <pre><code>let mut line = Line { text: "foo".to_owned(), column: "" }; line.column = &amp;self.text; line.text = "bar".to_owned(); // Uh oh, column is now invalid, pointing to freed memory </code></pre> <p>There is no way around this while the two values are stored together; they must be stored separately. The workaround that is most likely to be suitable for your case is to store indexes, e.g. start and end indexes as <code>(usize, usize)</code>.</p> <p>Now: why these particular errors? It comes down to what <code>'a</code> is being inferred as; your vector of lines is <code>Vec&lt;Lines&lt;'x&gt;&gt;</code> for a single lifetime <code>'x</code>: <em>each <code>Lines</code> instance has the same lifetime</em>. This means that the inferred lifetime must be greater than that of the loop, and so each iteration of the loop does indeed keep a mutable reference alive, and so the line does in fact conflict with itself (or rather, a previous iteration) in that way. The loop is not unrolled—it’s just the borrows from the loop are indeed still alive.</p> <p>This tip was originally posted on <a href="http://stackoverflow.com/questions/31238317/Mutable%20borrow%20conflict%20from%20unrolled%20loop/31239838">Stack Overflow</a>.</p>
comments powered by Disqus