<p dir="auto">The following code results in corrupt output: (Ubuntu 12.04 LTS, rust master pulled 25th Feb)</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="let arr : ~[&amp;str] = std::os::args()[1].split_str(&quot;::&quot;).collect();
std::io::println(&quot;first &quot; + arr[0]);
std::io::println(&quot;first again &quot; + arr[0]);"><pre class="notranslate"><code class="notranslate">let arr : ~[&amp;str] = std::os::args()[1].split_str("::").collect();
std::io::println("first " + arr[0]);
std::io::println("first again " + arr[0]);
</code></pre></div>
<p dir="auto">$ rustc isolate_issue.rs<br>
$ ./isolate_issue "foo::bar"<br>
first fir<br>
first again </p>
<p dir="auto">Ashish Myles noted that an earlier version of rust failed to compile this code, giving an error about the reference to the return value of std::os::args() not being valid for the duration of its use.</p>
<p dir="auto"><a href="https://mail.mozilla.org/pipermail/rust-dev/2014-February/008796.html" rel="nofollow">https://mail.mozilla.org/pipermail/rust-dev/2014-February/008796.html</a></p>
<p dir="auto">Pulling 'args' into a separate local variable works:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="let args = std::os::args();
let arr : ~[&amp;str] = args[1].split_str(&quot;::&quot;).collect();
std::io::println(&quot;first &quot; + arr[0]);
std::io::println(&quot;first again &quot; + arr[0]);"><pre class="notranslate"><code class="notranslate">let args = std::os::args();
let arr : ~[&amp;str] = args[1].split_str("::").collect();
std::io::println("first " + arr[0]);
std::io::println("first again " + arr[0]);
</code></pre></div>
<p dir="auto">$ ./isolate_issue "foo::bar"<br>
first foo<br>
first again foo</p>
<h1 dir="auto">Updated bug</h1>
<p dir="auto">The compiler allows this code when it shouldn't</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="fn main() {
    let a = ~&quot;&quot;;
    let b: ~[&amp;str] = a.lines().collect();
    drop(a);
    for s in b.iter() {
        println!(&quot;{}&quot;, *s);
    }
}"><pre class="notranslate"><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> a = ~""<span class="pl-kos">;</span>
    <span class="pl-k">let</span> b<span class="pl-kos">:</span> ~<span class="pl-kos">[</span><span class="pl-c1">&amp;</span><span class="pl-smi">str</span><span class="pl-kos">]</span> = a<span class="pl-kos">.</span><span class="pl-en">lines</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">collect</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-en">drop</span><span class="pl-kos">(</span>a<span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">for</span> s <span class="pl-k">in</span> b<span class="pl-kos">.</span><span class="pl-en">iter</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-en">println</span><span class="pl-en">!</span><span class="pl-kos">(</span><span class="pl-s">"{}"</span>, *s<span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<h1 dir="auto">Original description</h1>
<p dir="auto">The following code is buggy:</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="let foo = ~&quot;hello&quot;;
let foo: ~[&amp;str] = foo.words().collect();
let invalid_string = foo[0];"><pre class="notranslate"><span class="pl-k">let</span> foo = ~"hello"<span class="pl-kos">;</span>
<span class="pl-k">let</span> foo<span class="pl-kos">:</span> ~<span class="pl-kos">[</span><span class="pl-c1">&amp;</span><span class="pl-smi">str</span><span class="pl-kos">]</span> = foo<span class="pl-kos">.</span><span class="pl-en">words</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">collect</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">let</span> invalid_string = foo<span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">Invalid string contains, as the name suggests, an invalid string; sometimes I get a string filled with <code class="notranslate">\x00</code>, sometimes just garbage, and usually it will eventually assert that the string contains invalid characters.</p>
<p dir="auto">It appears that the first <code class="notranslate">foo</code> gets dropped when the second one is assigned?<br>
Either the first <code class="notranslate">foo</code> is supposed to be dropped as happens now, and the borrow checker should forbid this code (since the old <code class="notranslate">foo</code> no longer exists, <code class="notranslate">&amp;str</code> cannot have a lifetime), or it should let the first <code class="notranslate">foo</code> live until the end of the current scope, and make the above work.</p>