title: Scala - type inference of generic parameter with traits
body: <p>I'm working on an small rendering engine in Scala to learn the language. The architecture of the engine is strongly based on traits, so I can add and remove parts of the pipeline as I want. Some of the traits are: </p>
  
  <p>(<strong>update</strong>: Corrected some type information)</p>
  
  <pre><code>trait Composable { val parent:DisplayObject with Composite = null }
  trait Composite extends Composable { val children:ArrayBuffer[DisplayObject with Composable] = ArrayBuffer() }
  trait Position { var x = 0.0d; var y = 0.0d }
  ...
  </code></pre>
  
  <p><code>DisplayObject</code> is an empty class that is used to compose those traits.</p>
  
  <p>One of the step in my pipeline is flattening a hierarchy of each object. My first shot at this was was: 
  (<strong>update</strong>: I added the body)</p>
  
  <pre><code>def flatten(root:DisplayObject with Composite) : ArrayBuffer[DisplayObject] =
  {
      def traverse(composite:Composite, acc:ArrayBuffer[DisplayObject])
      {
        acc += composite
        for(composable &lt;- composite.children)
        {
          composable match {
            case com:Composite =&gt; traverse(com, acc)
            case _ =&gt; acc += composable
          }
        }
      }
  
      val flat = new ArrayBuffer[DisplayObject]
      traverse(root, flat)
      flat
    }
  }
  </code></pre>
  
  <p>This is fine, however, when I'm calling this function, I'm loosing a lot of type information:</p>
  
  <pre><code>val root = new DisplayObject with Position with Composite
  root.children += new DisplayObject with Composable with Position
  val list = flatten(root)
  </code></pre>
  
  <p>The type of <code>list</code> is now <code>List[DisplayObject]</code>. I'm losing the Position information. So I thought about adding generics into the mix : 
  (<strong>update</strong>: added body)</p>
  
  <pre><code>  def genericFlatten[T](root:T with Composite) : ArrayBuffer[T] =
    {
      def traverse(composite:T with Composite, acc:ArrayBuffer[T])
      {
        acc += composite
        for(composable &lt;- composite.children)
        {
          composable match {
            case com:T with Composite =&gt; traverse(com, acc)
            case composable:T with Composable =&gt; acc += composable
          }
        }
      }
  
      val flat = new ArrayBuffer[T]
      traverse(root, flat)
      flat
    }
  </code></pre>
  
  <p>However, calling this gives me this weird result : the type of the returned list is now <code>List[DisplayObject with Position with Composite]</code>, which is wrong, because some children of the tree (the leafs) will not have the Composite trait. I was expecting the type T to be infered to <code>DisplayObject with Position</code>. No?</p>