title: Erasure of type fields
body: <pre><code>abstract class Handler {
    type Message
  
    def handleAny(msg: Any) {
      if (msg.isInstanceOf[Message]) handle(msg.asInstanceOf[Message]) // fix me!
    }
  
    def handle(msg: Message)
  }
  
  class StringHandler extends Handler {
    override type Message = String
  
    def handle(msg: Message) { println(s"handling: $msg") }
  }
  
  val h = new StringHandler
  h.handleAny("ahoj")
  h.handleAny(true)
  </code></pre>
  
  <hr>
  
  <pre><code>warning: abstract type Handler.this.Message is unchecked since it is
   eliminated by erasure
                  if(msg.isInstanceOf[Message]) handle(msg.asInstanceOf[Message])
                                     ^
  one warning found
  handling: ahoj
  java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.String
          at Main$$anon$1$StringHandler.handle(typeProblem.scala:11)
          at Main$$anon$1$Handler.handleAny(typeProblem.scala:5)
  </code></pre>
  
  <p><strong>How to change the snippet</strong> (without changing interface or replacing type field with type parameter) to work as expected, which is <strong>to handle only messages specified by the type field</strong>?</p>
  
  <p>I'm looking for a solution which can be applied to the parent abstract class rather than polluting all children.</p>
  
  <p>I also tried to use a <code>match</code> and it behaves exactly same. Or is this kind of thing impossible with type fields (I thought they are more powerful than type parameters)?</p>