title: Alternative to equality constraints for associated types
body: <p>I'm trying to write this in Rust:</p>
  <pre><code>trait Foo {
      type T: PartialEq;
  
      fn get_t(&amp;self) -&gt; Self::T;
  }
  
  struct Bar&lt;F1: Foo, F2: Foo&gt; {
      f1: F1,
      f2: F2,
  }
  
  impl&lt;F1: Foo, F2: Foo&gt; Bar&lt;F1, F2&gt; {
      
      fn test_eq(&amp;self) -&gt; bool {
          self.f1.get_t() == self.f2.get_t()
      }
  }
  </code></pre>
  <p>It refuses to compile, because <code>F1::T</code> might be different from <code>F2::T</code>, rendering the equality meaningless. I'd like to be able to resolve that by writing this:</p>
  <pre><code>impl&lt;F1: Foo, F2: Foo&gt; Bar&lt;F1, F2&gt;
  where
      F1::T = F2::T
  {
      
      fn test_eq(&amp;self) -&gt; bool {
          self.f1.get_t() == self.f2.get_t()
      }
  }
  </code></pre>
  <p>But that tells me that equality constraints are not yet supported and refers me to <a href="https://github.com/rust-lang/rust/issues/20041" rel="nofollow noreferrer">this issue</a>. Since it's been open since late 2014, I suspect it's not a feature that's arriving any time soon.</p>
  <p>I can do this, and it'll compile:</p>
  <pre><code>struct Bar&lt;T: PartialEq, F1: Foo&lt;T=T&gt;, F2: Foo&lt;T=T&gt;&gt; {
      f1: F1,
      f2: F2,
  }
  
  impl&lt;T: PartialEq, F1: Foo&lt;T=T&gt;, F2: Foo&lt;T=T&gt;&gt; Bar&lt;T, F1, F2&gt;
  {
      
      fn test_eq(&amp;self) -&gt; bool {
          self.f1.get_t() == self.f2.get_t()
      }
  }
  </code></pre>
  <p>But then I'm adding an additional generic parameter to the struct <code>Bar</code>. If <code>Foo</code> has multiple associated types that I want to constrain in this manner, then it'll get a bit messy.
  My question is:</p>
  <ol>
  <li>Is this really the only way I can enforce this constraint, by making <code>Bar</code> 'more generic' with the addition of the additional type parameter <code>T</code>?</li>
  <li>Is this the most idiomatic way of solving this?</li>
  </ol>
  <p><em>Edit:</em></p>
  <p>I realize I simplified my example too much.
  Suppose I actually have a <code>Bar</code> that has an associated <code>Baz</code> that has an associated <code>Foo</code> that has an associated <code>T</code>.
  That's bit of a mouthful, so here is the example:</p>
  <pre><code>trait Foo {
      type T: PartialEq;
  
      fn get_t(&amp;self) -&gt; Self::T;
  }
  
  trait Baz {
      type F: Foo;
  
      fn get_inner_t(&amp;self) -&gt; &lt;Self::F as Foo&gt;::T;
  }
  
  struct Bar&lt;B1: Baz, B2: Baz&gt; {
      b1: B1,
      b2: B2,
  }
  
  impl&lt;B1: Baz, B2: Baz&gt; Bar&lt;B1, B2&gt;
  {
      
      fn test_eq(&amp;self) -&gt; bool {
          self.b1.get_inner_t() == self.b2.get_inner_t()
      }
  }
  </code></pre>
  <p>Of course it still doesn't compile because the <code>T</code>s from <code>get_inner_t</code> can differ. I do genuinely want to allow that the two <code>Baz</code>s differ, and the <code>Foo</code>s differ, but constrain their <code>T</code>s to be the same.</p>
  <p>I've tried to adapt the answer given, by writing</p>
  <pre><code>impl&lt;B1: Baz, B2: Baz&lt; &lt;F as Foo&gt;::T = B1::F::T &gt;&gt; Bar&lt;B1, B2&gt;
  </code></pre>
  <p>But that gives this compile error:</p>
  <pre><code>   Compiling type_bindings v0.1.0 (/home/harry/coding/rust_sandbox/type_bindings)
  error: expected one of `(`, `,`, `::`, `&lt;`, or `&gt;`, found `=`
    --&gt; src/main.rs:18:38
     |
  18 | impl&lt;B1: Baz, B2: Baz&lt; &lt;F as Foo&gt;::T = B1::F::T &gt;&gt; Bar&lt;B1, B2&gt;
     |                                      ^ expected one of `(`, `,`, `::`, `&lt;`, or `&gt;`
  
  error: aborting due to previous error
  
  error: could not compile `type_bindings`
  
  To learn more, run the command again with --verbose.
  </code></pre>
  <p>If this multi-level extraction of associated types not permitted?</p>