Skip to content

Commit

Permalink
Fix #19445: Remove too-strict test in match type matching.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sjrd committed Jan 22, 2024
1 parent 30bdc33 commit 1871cf6
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 1 deletion.
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3436,7 +3436,8 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
case MatchTypeCasePattern.BaseTypeTest(classType, argPatterns, needsConcreteScrut) =>
val cls = classType.classSymbol.asClass
scrut.baseType(cls) match
case base @ AppliedType(baseTycon, baseArgs) if baseTycon =:= classType =>
case base @ AppliedType(baseTycon, baseArgs) =>
// #19445 Don't check the prefix of baseTycon here; it is handled by `scrut <:< instantiatedPat`.
val innerScrutIsWidenedAbstract =
scrutIsWidenedAbstract
|| (needsConcreteScrut && !isConcrete(scrut)) // no point in checking concreteness if it does not need to be concrete
Expand Down
36 changes: 36 additions & 0 deletions tests/neg/i19445.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
-- [E007] Type Mismatch Error: tests/neg/i19445.scala:17:15 ------------------------------------------------------------
17 | val x: Int = ??? : UnwrapTypes[FooBar.Bar[Int]] // error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| Found: Test.UnwrapTypes[FooBar.Bar[Int]]
| Required: Int
|
| Note: a match type could not be fully reduced:
|
| trying to reduce Test.UnwrapTypes[FooBar.Bar[Int]]
| failed since selector FooBar.Bar[Int]
| does not match case BarFoo.Bar[x] => Test.UnwrapTypes[x]
| and cannot be shown to be disjoint from it either.
| Therefore, reduction cannot advance to the remaining cases
|
| case String => String
| case Int => Int
|
| longer explanation available when compiling with `-explain`
-- [E007] Type Mismatch Error: tests/neg/i19445.scala:18:28 ------------------------------------------------------------
18 | val tup: (Int, String) = ??? : UnwrapTypes[(FooBar.Bar[Int], FooBar.Bar[String])] // error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| Found: (Test.UnwrapTypes[FooBar.Bar[Int]], Test.UnwrapTypes[FooBar.Bar[String]])
| Required: (Int, String)
|
| Note: a match type could not be fully reduced:
|
| trying to reduce Test.UnwrapTypes[FooBar.Bar[Int]]
| failed since selector FooBar.Bar[Int]
| does not match case BarFoo.Bar[x] => Test.UnwrapTypes[x]
| and cannot be shown to be disjoint from it either.
| Therefore, reduction cannot advance to the remaining cases
|
| case String => String
| case Int => Int
|
| longer explanation available when compiling with `-explain`
19 changes: 19 additions & 0 deletions tests/neg/i19445.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
trait Foo:
case class Bar[A](value: A)

object FooBar extends Foo

object BarFoo extends Foo

object Test:
type UnwrapTypes[Xs] =
Xs match
case EmptyTuple => Xs
case x *: xs => UnwrapTypes[x] *: UnwrapTypes[xs]
case BarFoo.Bar[x] => UnwrapTypes[x]
case String => String
case Int => Int

val x: Int = ??? : UnwrapTypes[FooBar.Bar[Int]] // error
val tup: (Int, String) = ??? : UnwrapTypes[(FooBar.Bar[Int], FooBar.Bar[String])] // error
end Test
17 changes: 17 additions & 0 deletions tests/pos/i19445.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
trait Foo:
case class Bar[A](value: A)

object FooBar extends Foo

object Test:
type UnwrapTypes[Xs] =
Xs match
case EmptyTuple => Xs
case x *: xs => UnwrapTypes[x] *: UnwrapTypes[xs]
case Foo#Bar[x] => UnwrapTypes[x]
case String => String
case Int => Int

val x: Int = ??? : UnwrapTypes[FooBar.Bar[Int]]
val tup: (Int, String) = ??? : UnwrapTypes[(FooBar.Bar[Int], FooBar.Bar[String])]
end Test

0 comments on commit 1871cf6

Please sign in to comment.