Skip to content

Commit 6f9a2e2

Browse files
committed
Fix scala#6197: erase pattern bound type symbols completely
1 parent 9baef55 commit 6f9a2e2

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

compiler/src/dotty/tools/dotc/transform/patmat/Space.scala

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
322322
case Ident(nme.WILDCARD) =>
323323
Or(Typ(pat.tpe.stripAnnots, false) :: nullSpace :: Nil)
324324
case Ident(_) | Select(_, _) =>
325-
Typ(pat.tpe.stripAnnots, false)
325+
Typ(erase(pat.tpe.stripAnnots), false)
326326
case Alternative(trees) => Or(trees.map(project(_)))
327327
case Bind(_, pat) => project(pat)
328328
case SeqLiteral(pats, _) => projectSeq(pats)
@@ -338,16 +338,17 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
338338
Prod(erase(pat.tpe.stripAnnots), fun.tpe, fun.symbol, pats.take(arity - 1).map(project) :+ projectSeq(pats.drop(arity - 1)),isIrrefutableUnapply(fun))
339339
}
340340
else
341-
Prod(erase(pat.tpe.stripAnnots), fun.tpe, fun.symbol, pats.map(project), isIrrefutableUnapply(fun))
342-
case Typed(pat @ UnApply(_, _, _), _) => project(pat)
341+
Prod(erase(pat.tpe.stripAnnots), erase(fun.tpe), fun.symbol, pats.map(project), isIrrefutableUnapply(fun))
342+
case Typed(pat: UnApply, _) =>
343+
project(pat)
343344
case Typed(expr, tpt) =>
344345
Typ(erase(expr.tpe.stripAnnots), true)
345346
case This(_) =>
346347
Typ(pat.tpe.stripAnnots, false)
347348
case EmptyTree => // default rethrow clause of try/catch, check tests/patmat/try2.scala
348349
Typ(WildcardType, false)
349350
case _ =>
350-
debug.println(s"unknown pattern: $pat")
351+
ctx.error(s"unknown pattern: $pat", pat.sourcePos)
351352
Empty
352353
}
353354

@@ -364,13 +365,18 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
364365
}
365366

366367
/* Erase pattern bound types with WildcardType */
367-
def erase(tp: Type): Type = {
368+
def erase(tp: Type): Type = trace(i"$tp erased to", debug) {
368369
def isPatternTypeSymbol(sym: Symbol) = !sym.isClass && sym.is(Case)
369370

370371
val map = new TypeMap {
371372
def apply(tp: Type) = tp match {
373+
case tp @ AppliedType(tycon, args) if (tycon.isRef(defn.ArrayClass)) =>
374+
// cannot use WildcardType for Array[_], due to that
375+
// Array[WildcardType] <: Array[Array[WildcardType]]
376+
// see tests/patmat/t2425.scala
377+
TypeErasure.erasure(tp)
372378
case tref: TypeRef if isPatternTypeSymbol(tref.typeSymbol) =>
373-
tref.underlying.bounds
379+
WildcardType(tref.underlying.bounds)
374380
case _ => mapOver(tp)
375381
}
376382
}

tests/patmat/i6197.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
object Test {
2+
sealed trait Cause[+E]
3+
4+
object Cause {
5+
final case class Fail[E](value: E) extends Cause[E]
6+
}
7+
8+
def fn(cause: Cause[Any]): String =
9+
cause match {
10+
case Cause.Fail(t: Throwable) => t.toString
11+
case Cause.Fail(any) => any.toString
12+
}
13+
}

0 commit comments

Comments
 (0)