title: Type Erasure in Scala
body: <p>I'm rather confused about what's happening here:</p>
  
  <pre><code>import scala.collection.immutable._
  
  object Main extends App {
    sealed trait Node
  
    sealed trait Group
  
    case class Sheet(
      val splat: String,
      val charname: String, 
      val children: ListMap[String, Node],
      val params0: ListMap[String, Param], //params0 to separate sheet-general parameters
  
      val note: Option[Note]
      ) extends Node with Group
  
    case class Attributes(val name: String) extends Node with Group
  
    case class Param(val name: String, val value: String) extends Node
    case class Note(val note: String) extends Node
  </code></pre>
  
  <p>I've got three versions of a replace function - the last one is the one I'm actually trying to write, the others are just debugging.</p>
  
  <pre><code>  class SheetUpdater(s: Sheet) {    
      def replace1[T &lt;: Group](g: T): Unit = {
        s.children.head match {
          case (_, _:Sheet) =&gt;
          case (_, _:Attributes) =&gt;
        }
      }
    }
  </code></pre>
  
  <p>This version throws no warnings, so apparently I have access to the type of <code>s.children</code> at runtime.</p>
  
  <pre><code>  class SheetUpdater(s: Sheet) {
      def replace2[T &lt;: Group](g: T): Unit = {
        g match {
          case _:Sheet =&gt;
          case _:Attributes =&gt;
        }
      }
    }
  </code></pre>
  
  <p>Neither does this version, so apparently the details of <code>g</code>'s type are <em>also</em> available at runtime...</p>
  
  <pre><code>  class SheetUpdater(s: Sheet) {
      def replace3[T &lt;: Group](g: T): Unit = {
        s.children.head match {
          case (_, _:T) =&gt; //!
          case (_, _:Attributes) =&gt;
        }
      }
    }
  </code></pre>
  
  <p>... but even so, this ends up throwing me the dreaded <code>Abstract type pattern T is unchecked since it is eliminated by erasure</code> warning. What's going on here?</p>