title: Is there a way to convince Rust that a particular associated type is the same as a concrete type?
body: <p>Given the following traits and implementations:</p>
  
  <pre><code>trait Wrapper&lt;Type&gt; {
      type Inner : Wrapped&lt;Type&gt;;
      fn bind&lt;B, F&gt;(self, f: F) -&gt; &lt;B as Wrapped&lt;Type&gt;&gt;::Outer
          where B: Wrapped&lt;Type&gt;, F: Fn(Self::Inner) -&gt; &lt;B as Wrapped&lt;Type&gt;&gt;::Outer;
  }
  
  trait Wrapped&lt;Type&gt; {
      type Outer : Wrapper&lt;Type&gt;;
  }
  
  struct Opt;
  
  impl&lt;T&gt; Wrapped&lt;Opt&gt; for T {
      type Outer = Option&lt;T&gt;;
  }
  
  impl&lt;T&gt; Wrapper&lt;Opt&gt; for Option&lt;T&gt; {
      type Inner = T;
      fn bind&lt;B, F&gt;(self, f: F) -&gt; &lt;B as Wrapped&lt;Opt&gt;&gt;::Outer
          where B: Wrapped&lt;Opt&gt;, F: Fn(Self::Inner) -&gt; &lt;B as Wrapped&lt;Opt&gt;&gt;::Outer {
          match self {
              Some(a) =&gt; f(a),
              None =&gt; None,  // *** fails to compile
          }
      }
  }
  </code></pre>
  
  <p>It's obvious to a human that the type <code>&lt;B as Wrapped&lt;Opt&gt;&gt;::Outer</code> must always be <code>Option&lt;B&gt;</code>, but <code>rustc</code> can't seem to figure this out:</p>
  
  <pre><code>src/main.rs:47:21: 47:25 error: mismatched types:
   expected `&lt;B as Wrapped&lt;Opt&gt;&gt;::Outer`,
      found `core::option::Option&lt;_&gt;`
  (expected associated type,
      found enum `core::option::Option`) [E0308]
  src/main.rs:47             None =&gt; None,
                                     ^~~~
  </code></pre>
  
  <p>Is there any way to convince it that this is safe?  I'd even settle for an <code>unsafe</code> solution, but <code>mem::transmute</code> is also not allowed since it can't prove that the types are the same size and aligned (even though there's only one real type involved and not even any newtype wrappers that could mess up alignment).</p>