Skip to content

Commit 1871cf6

Browse files
committed
Fix #19445: Remove too-strict test in match type matching.
Previously, for a `BaseTypeTest`, we explicitly checked the prefix of the type constructor for `=:=`. This is however too strict, as shown by #19445. We remove the test entirely, as the correct subprefixing test is already part of the overall `scrut <:< instantiatedPat` done at the end.
1 parent 30bdc33 commit 1871cf6

File tree

4 files changed

+74
-1
lines changed

4 files changed

+74
-1
lines changed

Diff for: compiler/src/dotty/tools/dotc/core/TypeComparer.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -3436,7 +3436,8 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
34363436
case MatchTypeCasePattern.BaseTypeTest(classType, argPatterns, needsConcreteScrut) =>
34373437
val cls = classType.classSymbol.asClass
34383438
scrut.baseType(cls) match
3439-
case base @ AppliedType(baseTycon, baseArgs) if baseTycon =:= classType =>
3439+
case base @ AppliedType(baseTycon, baseArgs) =>
3440+
// #19445 Don't check the prefix of baseTycon here; it is handled by `scrut <:< instantiatedPat`.
34403441
val innerScrutIsWidenedAbstract =
34413442
scrutIsWidenedAbstract
34423443
|| (needsConcreteScrut && !isConcrete(scrut)) // no point in checking concreteness if it does not need to be concrete

Diff for: tests/neg/i19445.check

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
-- [E007] Type Mismatch Error: tests/neg/i19445.scala:17:15 ------------------------------------------------------------
2+
17 | val x: Int = ??? : UnwrapTypes[FooBar.Bar[Int]] // error
3+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
| Found: Test.UnwrapTypes[FooBar.Bar[Int]]
5+
| Required: Int
6+
|
7+
| Note: a match type could not be fully reduced:
8+
|
9+
| trying to reduce Test.UnwrapTypes[FooBar.Bar[Int]]
10+
| failed since selector FooBar.Bar[Int]
11+
| does not match case BarFoo.Bar[x] => Test.UnwrapTypes[x]
12+
| and cannot be shown to be disjoint from it either.
13+
| Therefore, reduction cannot advance to the remaining cases
14+
|
15+
| case String => String
16+
| case Int => Int
17+
|
18+
| longer explanation available when compiling with `-explain`
19+
-- [E007] Type Mismatch Error: tests/neg/i19445.scala:18:28 ------------------------------------------------------------
20+
18 | val tup: (Int, String) = ??? : UnwrapTypes[(FooBar.Bar[Int], FooBar.Bar[String])] // error
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
22+
| Found: (Test.UnwrapTypes[FooBar.Bar[Int]], Test.UnwrapTypes[FooBar.Bar[String]])
23+
| Required: (Int, String)
24+
|
25+
| Note: a match type could not be fully reduced:
26+
|
27+
| trying to reduce Test.UnwrapTypes[FooBar.Bar[Int]]
28+
| failed since selector FooBar.Bar[Int]
29+
| does not match case BarFoo.Bar[x] => Test.UnwrapTypes[x]
30+
| and cannot be shown to be disjoint from it either.
31+
| Therefore, reduction cannot advance to the remaining cases
32+
|
33+
| case String => String
34+
| case Int => Int
35+
|
36+
| longer explanation available when compiling with `-explain`

Diff for: tests/neg/i19445.scala

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
trait Foo:
2+
case class Bar[A](value: A)
3+
4+
object FooBar extends Foo
5+
6+
object BarFoo extends Foo
7+
8+
object Test:
9+
type UnwrapTypes[Xs] =
10+
Xs match
11+
case EmptyTuple => Xs
12+
case x *: xs => UnwrapTypes[x] *: UnwrapTypes[xs]
13+
case BarFoo.Bar[x] => UnwrapTypes[x]
14+
case String => String
15+
case Int => Int
16+
17+
val x: Int = ??? : UnwrapTypes[FooBar.Bar[Int]] // error
18+
val tup: (Int, String) = ??? : UnwrapTypes[(FooBar.Bar[Int], FooBar.Bar[String])] // error
19+
end Test

Diff for: tests/pos/i19445.scala

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
trait Foo:
2+
case class Bar[A](value: A)
3+
4+
object FooBar extends Foo
5+
6+
object Test:
7+
type UnwrapTypes[Xs] =
8+
Xs match
9+
case EmptyTuple => Xs
10+
case x *: xs => UnwrapTypes[x] *: UnwrapTypes[xs]
11+
case Foo#Bar[x] => UnwrapTypes[x]
12+
case String => String
13+
case Int => Int
14+
15+
val x: Int = ??? : UnwrapTypes[FooBar.Bar[Int]]
16+
val tup: (Int, String) = ??? : UnwrapTypes[(FooBar.Bar[Int], FooBar.Bar[String])]
17+
end Test

0 commit comments

Comments
 (0)