<p dir="auto"><em>I've created a <a href="http://www.reddit.com/r/rust/comments/2ba3az/macros_writeln_and_the_semicolon/" rel="nofollow">discussion topic</a> on Reddit, but for some reason it disappeared from the Rust page, so I'm filling an issue here. If there's a better place to discuss similar suggestions, please tell me.</em></p>
<p dir="auto">I was just playing with Rust on <a href="http://rustbyexample.com/" rel="nofollow">http://rustbyexample.com/</a>, and I've accidentally discovered that writeln can be called without a semicolon.<br>
It doesn't look like a big deal, but for a perfectionist like me, I see it as a consistency flaw, especially for (probably) the most common macro in the language.</p>
<p dir="auto">The author of <strong>Rust by example</strong> explained what's going on <a href="https://github.com/japaric/rust-by-example/issues/183" data-hovercard-type="issue" data-hovercard-url="/rust-lang/rust-by-example/issues/183/hovercard">here</a>, but that doesn't look right to me. Even C has a do-while(0) hack for this case.</p>
<p dir="auto"><a href="http://is.gd/ajFYN1" rel="nofollow">This</a> is an expanded <code class="notranslate">println!("test")</code>. The <code class="notranslate">match</code> looks very similar to the do-while(0) C hack for macros, and I think that it's the wrong way to do it, not only because it looks and feels like a hack, but also because it behaves differently than a native Rust function. For example, <code class="notranslate">println!("test") println!("test")</code> compiles, while <code class="notranslate">returns_unit() returns_unit()</code> doesn't.</p>
<p dir="auto">My proposal: use a self-calling function, similar to what <a href="http://stackoverflow.com/questions/592396/what-is-the-purpose-of-a-self-executing-function-in-javascript" rel="nofollow">JavaScript allows</a>. I don't know whether it's currently possible in Rust, but if not, I think it could be a natural addition to the language. <a href="http://is.gd/CZ7Y8u" rel="nofollow">Here's</a> how I expect it to look, more or less.</p>
<p dir="auto">I have encountered an issue which seems very unusual to me and I believe it might be a bug.</p>
<p dir="auto">Below is a small example which illustrates the issue.</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="struct CountDown {
    count: uint,
    // Including the vector causes `Some(self.current())` to fail later on.
    vector: Vec&lt;uint&gt;
}

impl CountDown {
    fn new() -&gt; CountDown {
        CountDown {
            count: 10,
            vector: vec!(3u, 4, 5)
        }
    }

    fn current(self) -&gt; uint {
        self.count
    }
}

impl Iterator&lt;uint&gt; for CountDown {
    fn next(&amp;mut self) -&gt; Option&lt;uint&gt; {
        self.count -= 1;
        if self.count == 0 {
            None
        } else {
            // Whether the vector is in the struct or not, this work:
            //Some(self.count)

            // When the struct contains a vector, the following causes the error:
            //   cannot move out of dereference of `&amp;mut`-pointer
            // If the vector is not in the struct, this work fine.
            Some(self.current())
        }
    }
}

fn main() {
    for n in CountDown::new() {
        println!(&quot;n = {}&quot;, n);
    }
}"><pre class="notranslate"><span class="pl-k">struct</span> <span class="pl-smi">CountDown</span> <span class="pl-kos">{</span>
    <span class="pl-c1">count</span><span class="pl-kos">:</span> <span class="pl-smi">uint</span><span class="pl-kos">,</span>
    <span class="pl-c">// Including the vector causes `Some(self.current())` to fail later on.</span>
    <span class="pl-c1">vector</span><span class="pl-kos">:</span> <span class="pl-smi">Vec</span><span class="pl-kos">&lt;</span><span class="pl-smi">uint</span><span class="pl-kos">&gt;</span>
<span class="pl-kos">}</span>

<span class="pl-k">impl</span> <span class="pl-smi">CountDown</span> <span class="pl-kos">{</span>
    <span class="pl-k">fn</span> <span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-kos">)</span> -&gt; <span class="pl-smi">CountDown</span> <span class="pl-kos">{</span>
        <span class="pl-smi">CountDown</span> <span class="pl-kos">{</span>
            <span class="pl-c1">count</span><span class="pl-kos">:</span> <span class="pl-c1">10</span><span class="pl-kos">,</span>
            <span class="pl-c1">vector</span><span class="pl-kos">:</span> <span class="pl-en">vec</span><span class="pl-en">!</span><span class="pl-kos">(</span><span class="pl-c1">3</span>u, <span class="pl-c1">4</span>, <span class="pl-c1">5</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">current</span><span class="pl-kos">(</span><span class="pl-smi">self</span><span class="pl-kos">)</span> -&gt; <span class="pl-smi">uint</span> <span class="pl-kos">{</span>
        <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-c1">count</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-k">impl</span> <span class="pl-smi">Iterator</span><span class="pl-kos">&lt;</span><span class="pl-smi">uint</span><span class="pl-kos">&gt;</span> <span class="pl-k">for</span> <span class="pl-smi">CountDown</span> <span class="pl-kos">{</span>
    <span class="pl-k">fn</span> <span class="pl-en">next</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> -&gt; <span class="pl-smi">Option</span><span class="pl-kos">&lt;</span><span class="pl-smi">uint</span><span class="pl-kos">&gt;</span> <span class="pl-kos">{</span>
        <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-c1">count</span> -= <span class="pl-c1">1</span><span class="pl-kos">;</span>
        <span class="pl-k">if</span> <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-c1">count</span> == <span class="pl-c1">0</span> <span class="pl-kos">{</span>
            <span class="pl-v">None</span>
        <span class="pl-kos">}</span> <span class="pl-k">else</span> <span class="pl-kos">{</span>
            <span class="pl-c">// Whether the vector is in the struct or not, this work:</span>
            <span class="pl-c">//Some(self.count)</span>

            <span class="pl-c">// When the struct contains a vector, the following causes the error:</span>
            <span class="pl-c">//   cannot move out of dereference of `&amp;mut`-pointer</span>
            <span class="pl-c">// If the vector is not in the struct, this work fine.</span>
            <span class="pl-v">Some</span><span class="pl-kos">(</span><span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">current</span><span class="pl-kos">(</span><span class="pl-kos">)</span><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">main</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">for</span> n <span class="pl-k">in</span> <span class="pl-smi">CountDown</span><span class="pl-kos">::</span><span class="pl-en">new</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">"n = {}"</span>, n<span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">It appears to me quite strange that the presence of a Vector within the struct (even if it isn't used) causes the issue.  It also seems strange to me that returning a struct field works, but returning a method which itself returns that struct field fails.</p>
<p dir="auto">Admittedly, I don't really understand what <code class="notranslate">cannot move out of dereference of '&amp;mut'-pointer</code> really means; a Google search doesn't yield very much, and the documentation doesn't seem to contain much regarding the error.</p>