title: Type mismatch on abstract type used in pattern matching
body: <p>This code compiles with an error:</p>
  
  <pre><code>def f1[T](e: T): T = e match {
    case i:Int =&gt; i
    case b:Boolean =&gt; b
  }
  // type mismatch;
  // found   : i.type (with underlying type Int)
  // required: T
  // case i:Int =&gt; i ...
  </code></pre>
  
  <p>And this code implementing GADT looks pretty identical from type checking perspective, but compiles without error:</p>
  
  <pre><code>sealed trait Expr[T]
  case class IntExpr(i: Int) extends Expr[Int]
  case class BoolExpr(b: Boolean) extends Expr[Boolean]
  
  def eval[T](e: Expr[T]): T = e match {
    case IntExpr(i) =&gt; i
    case BoolExpr(b) =&gt; b
  }
  </code></pre>
  
  <p>In both cases inside pattern matching expression we know that <strong>i</strong> and <strong>b</strong> are <strong>Int</strong> and <strong>Boolean</strong>. Why compilation failed on first example and succeeded on the second one? </p>