title: Swift generic child type always returns parent
body: <p>I'm trying to do a container pool of generics, however I find that when trying to recycle from a parent class, the generic inference can't be resolved properly and I just get the parent type instead of the concrete one</p>
  <p>An example:</p>
  <pre><code>Enemy : Poolable {
  
  
     func die() {
         containerPool.recycle(self)
     }
  
  }
  
  Enemy2 : Enemy {
  
  }
  
  
  containerPool.obtain(Enemy2.self).die() //Crash with Could not cast value of type Pool&lt;Enemy2&gt; to Pool&lt;Enemy&gt;
  </code></pre>
  <p>//The container pool recycle method:</p>
  <pre><code>import Foundation
  
  protocol Poolable {
      init()
      func onRecycled()
      func willBeObtained()
  }
  
  class Pool&lt;T:Poolable&gt; {
      
      var objects:[T] = []
      
      init(initialSpawn:Int = 0){
          for _ in 0...initialSpawn {
              objects.append(T.init())
          }
      }
      
      func obtain() -&gt; T {
          if objects.count &gt; 0 {
              let object = objects.removeFirst()
              object.willBeObtained()
              return object
          }
          let object = T.init()
          object.willBeObtained()
          return object
      }
      
      func recycle(_ object:T) {
          object.onRecycled()
          objects.append(object)
      }
      
  }
  
  class ContainerPool {
      
      var pools:[String:Any] = [:]
      
      func obtain&lt;T:Poolable&gt;() -&gt; T {
          pool(for:T.self).obtain()
      }
      
      func obtain&lt;T:Poolable&gt;(_ type:T.Type) -&gt; T{
          pool(for:type).obtain()
      }
      
      func recycle&lt;T:Poolable&gt;(_ object:T) {
          let concreteType = type(of: object)
          pool(for: concreteType).recycle(object)
      }
      
      func pool&lt;T:Poolable&gt;(for type:T.Type, initialSpawn:Int = 10) -&gt; Pool&lt;T&gt; {
          let typeString = &quot;\(type)&quot;
          if let pool = pools[typeString] as? Pool&lt;T&gt; {
          //if let pool = pools[typeString] {
              return pool
          }
          let pool = Pool&lt;T&gt;(initialSpawn:initialSpawn)
          pools[typeString] = pool
          return pool
      }
          
      func preload&lt;T:Poolable&gt;(type:T.Type, size:Int = 20){
          let _ = pool(for: type, initialSpawn: size)
      }
      
  }
  </code></pre>
  <p>typeStrings is always right, and the pool I get in let pool is the right one, but I can't cast it to Enemy2 as it thinks the T is Enemy...</p>
  <p>Is there a way to solve it?</p>