<h3 dir="auto">STR</h3>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#[deriving(Clone)]
//~^ error: trait `Clone` already appears in the list of bounds [E0127]
struct Foo&lt;'a, T: 'a + Clone&gt; {
    foo: &amp;'a [T],
}

fn main() {}"><pre class="notranslate"><span class="pl-c1">#<span class="pl-kos">[</span>deriving<span class="pl-kos">(</span><span class="pl-v">Clone</span><span class="pl-kos">)</span><span class="pl-kos">]</span></span>
<span class="pl-c">//~^ error: trait `Clone` already appears in the list of bounds [E0127]</span>
<span class="pl-k">struct</span> <span class="pl-smi">Foo</span><span class="pl-kos">&lt;</span><span class="pl-c1">'</span><span class="pl-ent">a</span><span class="pl-kos">,</span> <span class="pl-smi">T</span><span class="pl-kos">:</span> <span class="pl-c1">'</span><span class="pl-ent">a</span> + <span class="pl-smi">Clone</span><span class="pl-kos">&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-c1">foo</span><span class="pl-kos">:</span> <span class="pl-c1">&amp;</span><span class="pl-c1">'</span><span class="pl-ent">a</span> <span class="pl-kos">[</span><span class="pl-smi">T</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-kos">}</span></pre></div>
<h3 dir="auto">Output</h3>
<p dir="auto">If you look at the <code class="notranslate">--pretty=expanded</code> version, you'll see <code class="notranslate">T</code> is bounded twice by the <code class="notranslate">Clone</code> trait</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#![feature(phase)]
#![no_std]
#![feature(globs)]
#[phase(plugin, link)]
extern crate &quot;std&quot; as std;
#[prelude_import]
use std::prelude::*;
//~^ error: trait `Clone` already appears in the list of bounds [E0127]
struct Foo&lt;'a, T: 'a + Clone&gt; {
    foo: &amp;'a [T],
}
#[automatically_derived]
impl &lt;'a, T: ::std::clone::Clone + 'a + Clone&gt; ::std::clone::Clone for
     Foo&lt;'a, T&gt; {
    #[inline]
    fn clone(&amp;self) -&gt; Foo&lt;'a, T&gt; {
        match *self {
            Foo { foo: ref __self_0_0 } =&gt;
            Foo{foo: ::std::clone::Clone::clone(&amp;(*__self_0_0)),},
        }
    }
}"><pre class="notranslate"><span class="pl-c1">#!<span class="pl-kos">[</span>feature<span class="pl-kos">(</span>phase<span class="pl-kos">)</span><span class="pl-kos">]</span></span>
<span class="pl-c1">#!<span class="pl-kos">[</span>no_std<span class="pl-kos">]</span></span>
<span class="pl-c1">#!<span class="pl-kos">[</span>feature<span class="pl-kos">(</span>globs<span class="pl-kos">)</span><span class="pl-kos">]</span></span>
<span class="pl-c1">#<span class="pl-kos">[</span>phase<span class="pl-kos">(</span>plugin, link<span class="pl-kos">)</span><span class="pl-kos">]</span></span>
<span class="pl-k">extern</span> <span class="pl-k">crate</span> <span class="pl-s">"std"</span> as std<span class="pl-kos">;</span>
<span class="pl-c1">#<span class="pl-kos">[</span>prelude_import<span class="pl-kos">]</span></span>
<span class="pl-k">use</span> std<span class="pl-kos">::</span>prelude<span class="pl-kos">::</span><span class="pl-c1">*</span><span class="pl-kos">;</span>
<span class="pl-c">//~^ error: trait `Clone` already appears in the list of bounds [E0127]</span>
<span class="pl-k">struct</span> <span class="pl-smi">Foo</span><span class="pl-kos">&lt;</span><span class="pl-c1">'</span><span class="pl-ent">a</span><span class="pl-kos">,</span> <span class="pl-smi">T</span><span class="pl-kos">:</span> <span class="pl-c1">'</span><span class="pl-ent">a</span> + <span class="pl-smi">Clone</span><span class="pl-kos">&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-c1">foo</span><span class="pl-kos">:</span> <span class="pl-c1">&amp;</span><span class="pl-c1">'</span><span class="pl-ent">a</span> <span class="pl-kos">[</span><span class="pl-smi">T</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
<span class="pl-kos">}</span>
<span class="pl-c1">#<span class="pl-kos">[</span>automatically_derived<span class="pl-kos">]</span></span>
<span class="pl-k">impl</span> <span class="pl-kos">&lt;</span><span class="pl-c1">'</span><span class="pl-ent">a</span><span class="pl-kos">,</span> <span class="pl-smi">T</span><span class="pl-kos">:</span> <span class="pl-kos">::</span>std<span class="pl-kos">::</span>clone<span class="pl-kos">::</span><span class="pl-smi">Clone</span> + <span class="pl-c1">'</span><span class="pl-ent">a</span> + <span class="pl-smi">Clone</span><span class="pl-kos">&gt;</span> <span class="pl-kos">::</span>std<span class="pl-kos">::</span>clone<span class="pl-kos">::</span><span class="pl-smi">Clone</span> <span class="pl-k">for</span>
     <span class="pl-smi">Foo</span><span class="pl-kos">&lt;</span><span class="pl-c1">'</span><span class="pl-ent">a</span><span class="pl-kos">,</span> <span class="pl-smi">T</span><span class="pl-kos">&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-c1">#<span class="pl-kos">[</span>inline<span class="pl-kos">]</span></span>
    <span class="pl-k">fn</span> <span class="pl-en">clone</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">Foo</span><span class="pl-kos">&lt;</span><span class="pl-c1">'</span><span class="pl-ent">a</span><span class="pl-kos">,</span> <span class="pl-smi">T</span><span class="pl-kos">&gt;</span> <span class="pl-kos">{</span>
        <span class="pl-k">match</span> <span class="pl-c1">*</span><span class="pl-smi">self</span> <span class="pl-kos">{</span>
            <span class="pl-smi">Foo</span> <span class="pl-kos">{</span> <span class="pl-c1">foo</span><span class="pl-kos">:</span> <span class="pl-k">ref</span> __self_0_0 <span class="pl-kos">}</span> =&gt;
            <span class="pl-smi">Foo</span><span class="pl-kos">{</span><span class="pl-c1">foo</span><span class="pl-kos">:</span> <span class="pl-kos">::</span>std<span class="pl-kos">::</span>clone<span class="pl-kos">::</span><span class="pl-smi">Clone</span><span class="pl-kos">::</span><span class="pl-en">clone</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span><span class="pl-kos">(</span><span class="pl-c1">*</span>__self_0_0<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-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<h3 dir="auto">Version</h3>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="rustc 0.13.0-dev (82fc1aa87 2014-11-27 10:11:19 +0000)"><pre class="notranslate">rustc <span class="pl-c1">0.13</span><span class="pl-kos">.</span><span class="pl-c1">0</span>-<span class="pl-en">dev</span> <span class="pl-kos">(</span><span class="pl-c1">82</span>fc1aa87 <span class="pl-c1">2014</span>-<span class="pl-c1">11</span>-<span class="pl-c1">27</span> <span class="pl-c1">10</span><span class="pl-kos">:</span><span class="pl-c1">11</span><span class="pl-kos">:</span><span class="pl-c1">19</span> +<span class="pl-c1">0000</span><span class="pl-kos">)</span></pre></div>
<p dir="auto">The obvious fix seems to make the <code class="notranslate">deriving</code> syntax extension filter out the duplicated <code class="notranslate">Clone</code> just by looking at the trait name. The problem is that <code class="notranslate">::std::clone::Clone</code> may not be the same trait as <code class="notranslate">Clone</code>, but AFAIK the syntax extension can't know that, since that (path) information is collected <em>after</em> macro expansion.</p>
<h3 dir="auto">Work-around</h3>
<p dir="auto">One workaround to this issue is using the fact that the <code class="notranslate">deriving</code> syntax extension doesn't look at <code class="notranslate">where</code> bounds (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="50292921" data-permission-text="Title is private" data-url="https://github.com/rust-lang/rust/issues/19358" data-hovercard-type="issue" data-hovercard-url="/rust-lang/rust/issues/19358/hovercard" href="https://github.com/rust-lang/rust/issues/19358">#19358</a>), the following code compiles:</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#[deriving(Clone)]
struct Foo&lt;'a, T: 'a&gt; where T: Clone {
    foo: &amp;'a [T],
}

fn main() {}"><pre class="notranslate"><span class="pl-c1">#<span class="pl-kos">[</span>deriving<span class="pl-kos">(</span><span class="pl-v">Clone</span><span class="pl-kos">)</span><span class="pl-kos">]</span></span>
<span class="pl-k">struct</span> <span class="pl-smi">Foo</span><span class="pl-kos">&lt;</span><span class="pl-c1">'</span><span class="pl-ent">a</span><span class="pl-kos">,</span> <span class="pl-smi">T</span><span class="pl-kos">:</span> <span class="pl-c1">'</span><span class="pl-ent">a</span><span class="pl-kos">&gt;</span> <span class="pl-k">where</span> <span class="pl-smi">T</span><span class="pl-kos">:</span> <span class="pl-smi">Clone</span> <span class="pl-kos">{</span>
    <span class="pl-c1">foo</span><span class="pl-kos">:</span> <span class="pl-c1">&amp;</span><span class="pl-c1">'</span><span class="pl-ent">a</span> <span class="pl-kos">[</span><span class="pl-smi">T</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-kos">}</span></pre></div>
<p dir="auto">(Should this be an RFC?)</p>
<h2 dir="auto">Motivation</h2>
<p dir="auto">When refactoring, one may have dozens or hundreds of build errors which need to be fixed one by one. Sometimes, a build error is only a consequence of an earlier error rather than something that need to be fixed itself:</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="let foo = bar.method_that_was_renamed(); // First error
// ...
bar.other_method() // Second error because the type of `bar` is unknown"><pre class="notranslate"><span class="pl-k">let</span> foo = bar<span class="pl-kos">.</span><span class="pl-en">method_that_was_renamed</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// First error</span>
<span class="pl-c">// ...</span>
bar<span class="pl-kos">.</span><span class="pl-en">other_method</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c">// Second error because the type of `bar` is unknown</span><span class="pl-kos"></span></pre></div>
<p dir="auto">In such cases, it is a better strategy to start by looking at and fixing earlier errors (in the compiler output) first. The second error might just go away when the first is fixed.</p>
<p dir="auto">In a large enough crate, it’s easy to get well over one screenful of compiler output. So the workflow is something like:</p>
<ul dir="auto">
<li>Build. See lots of output be generated too fast to read.</li>
<li>Scroll back to the beginning of the output for this build. Don’t miss it! It looks a lot like the output of the previous build.</li>
<li>Find the first error.</li>
<li>Try to fix the first error.</li>
<li>Repeat.</li>
</ul>
<h2 dir="auto">Proposal</h2>
<p dir="auto">Add a command-line argument to rustc, called something like <code class="notranslate">--fatal</code>. When it is given and the compile finds a build error (the kind that would cause the compilation to fail eventually, so not warnings), exit immediately after printing diagnostics for this error. This is the opposite of the usual strategy of finding as many errors as possible at once.</p>
<p dir="auto">The new workflow is:</p>
<ul dir="auto">
<li>Build.</li>
<li>The first error is right there at the bottom of the terminal. A single error likely fits entirely on the screen.</li>
<li>Try to fix it.</li>
<li>Repeat.</li>
</ul>
<p dir="auto">(With some <a href="https://exyr.org/2011/inotify-run/" rel="nofollow">inotify-based tricks</a>, it’s not even necessary to switch focus from the terminal.)</p>