<p dir="auto">This has been bugging me for a while:</p>
<p dir="auto">To guard yourself against mistakes, it's nice to use type aprameters to give a type signatures that depend on its unit, without having any actual members of type T in the structure. Example:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="#[derive(Copy)]
pub struct Vector2D&lt;T&gt; {
  pub x: f32,
  pub y: f32,
}"><pre class="notranslate"><code class="notranslate">#[derive(Copy)]
pub struct Vector2D&lt;T&gt; {
  pub x: f32,
  pub y: f32,
}
</code></pre></div>
<p dir="auto">And make sure operators such as Add only work on vectors of the same space.<br>
Ok, now the problem is that unless T also implements Copy, Vector2D does not actually implement Copy.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="fn foo&lt;T&gt;(a: Vector2D&lt;T&gt;) {
  let b = a;
  let c = a;
  // ...
}"><pre class="notranslate"><code class="notranslate">fn foo&lt;T&gt;(a: Vector2D&lt;T&gt;) {
  let b = a;
  let c = a;
  // ...
}
</code></pre></div>
<p dir="auto">The compiler says:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="error: use of moved value: `a`
`a` moved here because it has type `math::Vector2D&lt;T&gt;`, which is non-copyable"><pre class="notranslate"><code class="notranslate">error: use of moved value: `a`
`a` moved here because it has type `math::Vector2D&lt;T&gt;`, which is non-copyable
</code></pre></div>
<p dir="auto">This can be worked around by specifying that T must be Copy in the definiton of foo</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="fn foo&lt;T: Copy&gt;(a: Vector&lt;T&gt;) {"><pre class="notranslate"><code class="notranslate">fn foo&lt;T: Copy&gt;(a: Vector&lt;T&gt;) {
</code></pre></div>
<p dir="auto">While this isn't a blocking issue, it is very confusing, since T is part of the type of Vector2D but isn't instanciated in the structure, so whether T implements copy should have no influence on whether Vector2D is copyable.<br>
The error message doesn't help because it doesn't say anything about T which is what is apparently confusing the compiler. Instead it points to the structure Vector2D which has derive(Foo) right next to it's definition.</p>
<p dir="auto">For example:</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#[deriving(Clone)]
struct Filter&lt;A, I, P&gt; where I: Iterator&lt;A&gt;, P: FnMut(&amp;A) -&gt; bool {
    it: I,
    p: P,
}"><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">Filter</span><span class="pl-kos">&lt;</span><span class="pl-smi">A</span><span class="pl-kos">,</span> <span class="pl-smi">I</span><span class="pl-kos">,</span> <span class="pl-smi">P</span><span class="pl-kos">&gt;</span> <span class="pl-k">where</span> <span class="pl-smi">I</span><span class="pl-kos">:</span> <span class="pl-smi">Iterator</span><span class="pl-kos">&lt;</span><span class="pl-smi">A</span><span class="pl-kos">&gt;</span><span class="pl-kos">,</span> <span class="pl-smi">P</span><span class="pl-kos">:</span> <span class="pl-smi">FnMut</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span><span class="pl-smi">A</span><span class="pl-kos">)</span> -&gt; <span class="pl-smi">bool</span> <span class="pl-kos">{</span>
    <span class="pl-c1">it</span><span class="pl-kos">:</span> <span class="pl-smi">I</span><span class="pl-kos">,</span>
    <span class="pl-c1">p</span><span class="pl-kos">:</span> <span class="pl-smi">P</span><span class="pl-kos">,</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">expands to:</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="impl&lt;A: Clone, I: Clone, P: Clone&gt; Clone for Filter&lt;A, I, P&gt; where /* .. */ { /* .. */ }"><pre class="notranslate"><span class="pl-k">impl</span><span class="pl-kos">&lt;</span><span class="pl-smi">A</span><span class="pl-kos">:</span> <span class="pl-smi">Clone</span><span class="pl-kos">,</span> <span class="pl-smi">I</span><span class="pl-kos">:</span> <span class="pl-smi">Clone</span><span class="pl-kos">,</span> <span class="pl-smi">P</span><span class="pl-kos">:</span> <span class="pl-smi">Clone</span><span class="pl-kos">&gt;</span> <span class="pl-smi">Clone</span> <span class="pl-k">for</span> <span class="pl-smi">Filter</span><span class="pl-kos">&lt;</span><span class="pl-smi">A</span><span class="pl-kos">,</span> <span class="pl-smi">I</span><span class="pl-kos">,</span> <span class="pl-smi">P</span><span class="pl-kos">&gt;</span> <span class="pl-k">where</span> <span class="pl-c">/* .. */</span> <span class="pl-kos">{</span> <span class="pl-c">/* .. */</span> <span class="pl-kos">}</span></pre></div>
<p dir="auto">The <code class="notranslate">A: Clone</code> bound is incorrect. Instead <code class="notranslate">deriving</code> should expand to:</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="impl&lt;A, I, P&gt; Clone for Filter&lt;A, I, P&gt; where
    I: Clone,
    P: Clone,
    /* .. */ { /* .. */ }"><pre class="notranslate"><span class="pl-k">impl</span><span class="pl-kos">&lt;</span><span class="pl-smi">A</span><span class="pl-kos">,</span> <span class="pl-smi">I</span><span class="pl-kos">,</span> <span class="pl-smi">P</span><span class="pl-kos">&gt;</span> <span class="pl-smi">Clone</span> <span class="pl-k">for</span> <span class="pl-smi">Filter</span><span class="pl-kos">&lt;</span><span class="pl-smi">A</span><span class="pl-kos">,</span> <span class="pl-smi">I</span><span class="pl-kos">,</span> <span class="pl-smi">P</span><span class="pl-kos">&gt;</span> <span class="pl-k">where</span>
    <span class="pl-smi">I</span><span class="pl-kos">:</span> <span class="pl-smi">Clone</span><span class="pl-kos">,</span>
    <span class="pl-smi">P</span><span class="pl-kos">:</span> <span class="pl-smi">Clone</span><span class="pl-kos">,</span>
    <span class="pl-c">/* .. */</span> <span class="pl-kos">{</span> <span class="pl-c">/* .. */</span> <span class="pl-kos">}</span></pre></div>
<p dir="auto">This requires generalized <code class="notranslate">where</code> clauses to handle more complex fields like <code class="notranslate">&amp;'a T: Clone</code>.</p>
<p dir="auto"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/nikomatsakis/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/nikomatsakis">@nikomatsakis</a> Are where clauses like <code class="notranslate">&amp;'a int: Clone</code> (note: no generic parameter) going to be allowed? If not, writing the syntax extension is going to be harder.</p>