title: Why does typealiasing a tuple of a generic protocol in Swift allow me to treat it as a non-generic protocol?
body: <p>I'm having trouble understanding why typealiasing a tuple of a generic protocol suddenly allows me to treat it as a non-generic protocol. Because of the way Swift generics work, we expect the errors we get in Examples 1, 3, 4 and 5. But why does Example 2 work? And how is it semantically different from Example 3?</p>
  
  <h1>Example 1:</h1>
  
  <p>As expected, this won't compile:</p>
  
  <pre><code>let foo: Hashable = "a" // error: protocol 'Hashable' can only be used as a generic constraint because it has Self or associated type requirements
  </code></pre>
  
  <p>Because <code>Hashable</code> inherits the <code>Self</code> requirement from <code>Equatable</code>.</p>
  
  <h1>Example 2:</h1>
  
  <p>But if I define a tuple of <code>Hashable</code>, it works!</p>
  
  <pre><code>typealias CompositeHashable = (Hashable, Hashable)
  let foo: CompositeHashable = (1, "a") // This works!
  </code></pre>
  
  <p>Now I no longer need to use <code>Hashable</code> as a generic constraint. </p>
  
  <h1>Example 2b:</h1>
  
  <p>I can even use <code>CompositeHashable</code> in a collection:</p>
  
  <pre><code>let bar: [CompositeHashable] = [(1, "a"), ("b", "a")] // This works!
  </code></pre>
  
  <h1>Example 3:</h1>
  
  <p>Interestingly, if I don't typealias the tuple, it doens't work.</p>
  
  <pre><code>let foo: (Hashable, Hashable) = (1, "a") // error: protocol 'Hashable' can only be used as a generic constraint because it has Self or associated type requirements
  </code></pre>
  
  <p>That should have been equivalent to Example 2, right?</p>
  
  <h1>Example 4:</h1>
  
  <p>Additionally, a 1-tuple doesn't work either, with or without typealias:</p>
  
  <pre><code>typealias HashableTuple = (Hashable)
  let foo: HashableTuple = ("a") // error: protocol 'Hashable' can only be used as a generic constraint because it has Self or associated type requirements
  </code></pre>
  
  <h1>Example 5:</h1>
  
  <p>One more piece to this.. if I take the previous typealias <code>CompositeHashable</code> from Example 2, and simply move it into a struct, it now gives the same error we expected in the other cases.</p>
  
  <pre><code>struct CompositeKey {
      typealias CompositeHashable = (Hashable, Hashable) // error: protocol 'Hashable' can only be used as a generic constraint because it has Self or associated type requirements
  }
  </code></pre>
  
  <p>Can anyone explain what's going on here?</p>