Skip to content

Commit 9166db3

Browse files
committed
Fix #3333: instantiate unconstrained tvars to Wildcard
1 parent 253f505 commit 9166db3

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,6 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
596596
// replace type parameter references with bounds
597597
val typeParamMap = new TypeMap {
598598
def apply(t: Type): Type = t match {
599-
600599
case tp: TypeRef if tp.symbol.is(TypeParam) && tp.underlying.isInstanceOf[TypeBounds] =>
601600
// See tests/patmat/gadt.scala tests/patmat/exhausting.scala tests/patmat/t9657.scala
602601
val exposed =
@@ -611,13 +610,32 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
611610
}
612611
}
613612

613+
// replace uninstantiated type vars with WildcardType, check tests/patmat/3333.scala
614+
val instUndetMap = new TypeMap {
615+
def apply(t: Type): Type = t match {
616+
case tvar: TypeVar if !tvar.isInstantiated => WildcardType(tvar.origin.underlying.bounds)
617+
case _ => mapOver(t)
618+
}
619+
}
620+
621+
val force = new ForceDegree.Value(
622+
tvar => !(ctx.typerState.constraint.entry(tvar.origin) eq tvar.origin.underlying),
623+
minimizeAll = false
624+
)
625+
614626
val tvars = tp1.typeParams.map { tparam => newTypeVar(tparam.paramInfo.bounds) }
615627
val protoTp1 = thisTypeMap(tp1.appliedTo(tvars))
616628

617-
if (protoTp1 <:< tp2 && isFullyDefined(protoTp1, ForceDegree.noBottom)) protoTp1
629+
if (protoTp1 <:< tp2) {
630+
isFullyDefined(protoTp1, force)
631+
instUndetMap(protoTp1)
632+
}
618633
else {
619634
val protoTp2 = typeParamMap(tp2)
620-
if (protoTp1 <:< protoTp2 && isFullyDefined(protoTp1 & protoTp2, ForceDegree.noBottom)) protoTp1
635+
if (protoTp1 <:< protoTp2) {
636+
isFullyDefined(protoTp1 & protoTp2, force)
637+
instUndetMap(protoTp1)
638+
}
621639
else {
622640
debug.println(s"$protoTp1 <:< $protoTp2 = false")
623641
NoType

tests/patmat/3333.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
10: Pattern Match Exhaustivity: _: IntNumber, NotNaN

tests/patmat/3333.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
sealed trait IntegralNumber
2+
3+
object IntegralNumber {
4+
object NaN extends IntegralNumber
5+
object NotNaN extends IntegralNumber
6+
7+
sealed abstract class FiniteNumberImpl[N](val value: N) extends IntegralNumber
8+
sealed class IntNumber(value: Int) extends FiniteNumberImpl[Int](value)
9+
10+
def test(o: IntegralNumber) = o match {
11+
case NaN => -1
12+
}
13+
14+
}

0 commit comments

Comments
 (0)