title: rust: Define a trait that returns a non consuming iterator. (associated type bounds for both T impls IntoIterator and &T impls IntoIterator)
body: <p>I want a trait that returns a generic collection and let me iterate over the references in that collection.</p>
  <p>e.g:</p>
  <pre><code>trait DuckCollection {
      type CollectionType: IntoIterator&lt;Item=Duck&gt;;
      fn get(self) -&gt; Self::CollectionType;
      fn as_ref(&amp;self) -&gt; &amp;Self::CollectionType;
  }
  </code></pre>
  <p>The consuming iterator works, however there is a problem with <code>as_ref</code>.</p>
  <pre><code>//doesn't work
  fn print&lt;T: DuckCollection&gt;(model: &amp;T) {
      let collection_ref = model.as_ref();
      for itemref in (collection_ref).into_iter() {
          println!(&quot;{:?}&quot;, *itemref);
      }  
  }
  </code></pre>
  <p>This doesn't work because when <code>.into_iter()</code> is called on <code>collection_ref</code>, <code>collection_ref</code> is coerced from <code>&amp;&lt;T as DuckCollection&gt;::CollectionType</code> to <code>&lt;T as DuckCollection&gt;::CollectionType</code> because <code>DuckCollection</code> does not know that <code>&amp;&lt;T as DuckCollection&gt;::CollectionType</code> also implements <code>IntoIterator</code></p>
  <p><a href="https://i.stack.imgur.com/susF0.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/susF0.png" alt="enter image description here" /></a></p>
  <p>This can be fixed by adding trait bounds to the function. i.e, the below works:</p>
  <pre><code>fn print&lt;'a, T: DuckCollection&gt;(model: &amp;'a T)
  where &amp;'a&lt;T as DuckCollection&gt;::CollectionType: IntoIterator&lt;Item=&amp;'a Duck&gt;
  {
      let collection_ref = model.as_ref();
      for itemref in collection_ref.into_iter() {
          println!(&quot;{:?}&quot;, *itemref);
      }  
  }
  </code></pre>
  <p>However, I would like to have this information in the trait itself, rather than in the code that uses it, so I tried to use a <code>where</code> clause in the trait return type, shown below, with the resulting error:</p>
  <pre><code>impl DuckCollection for Model {
      type CollectionType = Vec&lt;Duck&gt;;
      fn get(self) -&gt; Self::CollectionType {
          self.data
      }
      fn as_ref&lt;'a&gt;(&amp;'a self) -&gt; &amp;Self::CollectionType where &amp;'a&lt;Self&gt;::CollectionType: IntoIterator&lt;Item=&amp;'a Duck&gt; {
          &amp;self.data
      }
  }
  
  fn print&lt;T: DuckCollection&gt;(model: &amp;T)
  {
      let collection_ref = model.as_ref();
      for itemref in collection_ref.into_iter() {
          println!(&quot;{:?}&quot;, *itemref);
      }  
  }
  
  `&amp;&lt;T as DuckCollection&gt;::CollectionType` is not an iterator
  the trait `Iterator` is not implemented for `&amp;&lt;T as DuckCollection&gt;::CollectionType`
  required because of the requirements on the impl of `IntoIterator` for `&amp;&lt;T as DuckCollection&gt;::CollectionType`
  </code></pre>
  <p>The type is no longer being coerced, but it still doesn't realise that <code>&amp;&lt;T as DuckCollection&gt;::CollectionType</code> is an <code>IntoIterator</code>. (i.e both <code>Vec&lt;T&gt;</code> and <code>&amp;Vec&lt;T&gt;</code> impl <code>IntoIterator</code>). This is annoying because I'm pretty sure my <code>where</code> clause tells the compiler this.</p>
  <p>I've also tried using <code>associated_type_defaults</code> and <code>generic_associated_types</code>, to tell the trait that there is an associated type called <code>CollectionTypeRef</code>, that implement <code>IntoIterator</code>, and that the type is a reference of a <code>CollectionType</code>. Shown below with the error:</p>
  <pre><code>trait DuckCollection {
      type CollectionType: IntoIterator&lt;Item=Duck&gt;;
      type CollectionTypeRef&lt;'a&gt;: IntoIterator&lt;Item=&amp;'a Duck&gt; = &amp;'a Self::CollectionType;
      fn get(self) -&gt; Self::CollectionType;
      fn as_ref&lt;'a&gt;(&amp;self) -&gt; Self::CollectionTypeRef&lt;'a&gt;;
  }
  
  the associated type `&lt;Self as DuckCollection&gt;::CollectionType` may not live long enough
  ...so that the reference type `&amp;'a &lt;Self as DuckCollection&gt;::CollectionType` does not outlive the data it points at
  </code></pre>
  <p>How can I fix this? How can I tell the trait that <code>get</code> returns something that can be turned into an iterator of <code>Duck</code>, and <code>as_ref</code> returns an iterator of <code>&amp;Duck</code> ?</p>