@@ -364,7 +364,35 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
364364 (arity, elemTp, resultTp)
365365 }
366366
367- /* Erase pattern bound types with WildcardType */
367+ /** Erase pattern bound types with WildcardType
368+ *
369+ * For example, the type `C[T$1]` should match any `C[_]`, thus
370+ * `v` should be `WildcardType` instead of `T$1`:
371+ *
372+ * sealed trait B
373+ * case class C[T](v: T) extends B
374+ * (b: B) match {
375+ * case C(v) => // case C.unapply[T$1 @ T$1](v @ _):C[T$1]
376+ * }
377+ *
378+ * However, we cannot use WildcardType for Array[_], due to that
379+ * `Array[WildcardType] <: Array[Array[WildcardType]]`, which may
380+ * cause false unreachable warnings. See tests/patmat/t2425.scala
381+ *
382+ * We cannot use type erasure here, as it would lose the constraints
383+ * invovling GADTs. For example, in the following code, type
384+ * erasure would loose the constraint that `x` and `y` must be
385+ * the same type, resulting in false inexhaustive warnings:
386+ *
387+ * sealed trait Expr[T]
388+ * case class IntExpr(x: Int) extends Expr[Int]
389+ * case class BooleanExpr(b: Boolean) extends Expr[Boolean]
390+ *
391+ * def foo[T](x: Expr[T], y: Expr[T]) = (x, y) match {
392+ * case (IntExpr(_), IntExpr(_)) =>
393+ * case (BooleanExpr(_), BooleanExpr(_)) =>
394+ * }
395+ */
368396 private def erase (tp : Type , inArray : Boolean = false ): Type = trace(i " $tp erased to " , debug) {
369397 def isPatternTypeSymbol (sym : Symbol ) = ! sym.isClass && sym.is(Case )
370398
0 commit comments