Skip to content
Prev Previous commit
Next Next commit
refine patmat check for type erasure
  • Loading branch information
liufengyun committed Jul 5, 2016
commit 89e8ff917826529890b10aa157634cbe4c15e4ef
15 changes: 13 additions & 2 deletions src/dotty/tools/dotc/transform/patmat/Space.scala
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
Typ(tp.widenTermRefExpr.stripAnnots, false)
else
Var(pat.symbol, tp)
case tp => Typ(tp, false)
case tp => Typ(erase(tp), false)
}
case Alternative(trees) => Or(trees.map(project(_, roundUp)))
case Bind(_, pat) => project(pat)
Expand All @@ -261,11 +261,22 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
else if (roundUp) Typ(pat.tpe.stripAnnots, false)
else Empty
case Typed(pat @ UnApply(_, _, _), _) => project(pat)
case Typed(expr, _) => Typ(expr.tpe.stripAnnots, true)
case Typed(expr, _) => Typ(erase(expr.tpe.stripAnnots), true)
case _ =>
Empty
}

/* Erase a type binding according to erasure rule */
def erase(tp: Type): Type = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

counter-example

       (null) match { case a: (List[Int]| Stack[Int]) => }

I propose to use real erasure: TypeErasure.erasure(tp)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is addressed in the new PR by handling AND and OR-types explicitly. TypeErasure can't be simply reused here as I don't want Int | Boolean get erased to Object and the prefix in TypeRef removed.

def doErase(tp: Type): Type = tp match {
case tp: RefinedType => erase(tp.parent)
case _ => tp
}

val origin = doErase(tp)
if (origin =:= defn.ArrayType) tp else origin
}

/** Is `tp1` a subtype of `tp2`? */
def isSubType(tp1: Type, tp2: Type): Boolean = tp1 <:< tp2

Expand Down
15 changes: 15 additions & 0 deletions tests/patmat/t2425.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
trait B
class D extends B
object Test extends App {
def foo[T](bar: T) = {
bar match {
case _: Array[Array[_]] => println("array 2d")
case _: Array[_] => println("array 1d")
case _ => println("something else")
}
}
foo(Array.fill(10)(2))
foo(Array.fill(10, 10)(2))
foo(Array.fill(10, 10, 10)(2))
foo(List(1, 2, 3))
}