Skip to content

Commit 6508dfa

Browse files
authored
Merge pull request #15351 from dwijnand/gadt/unapply-tuple-reasoning-upcast
2 parents 9be5a34 + 1c3a286 commit 6508dfa

File tree

3 files changed

+48
-6
lines changed

3 files changed

+48
-6
lines changed

compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,28 @@ trait PatternTypeConstrainer { self: TypeComparer =>
138138
val andType = buildAndType(baseClasses)
139139
!andType.exists || constrainPatternType(pat, andType)
140140
case _ =>
141-
val upcasted: Type = scrut match {
142-
case scrut: TypeProxy => scrut.superType
143-
case _ => NoType
141+
def tryGadtBounds = scrut match {
142+
case scrut: TypeRef =>
143+
ctx.gadt.bounds(scrut.symbol) match {
144+
case tb: TypeBounds =>
145+
val hi = tb.hi
146+
constrainPatternType(pat, hi)
147+
case null => true
148+
}
149+
case _ => true
144150
}
145-
if (upcasted.exists)
146-
tryConstrainSimplePatternType(pat, upcasted) || constrainUpcasted(upcasted)
147-
else true
151+
152+
def trySuperType =
153+
val upcasted: Type = scrut match {
154+
case scrut: TypeProxy =>
155+
scrut.superType
156+
case _ => NoType
157+
}
158+
if (upcasted.exists)
159+
tryConstrainSimplePatternType(pat, upcasted) || constrainUpcasted(upcasted)
160+
else true
161+
162+
tryGadtBounds && trySuperType
148163
}
149164
}
150165

tests/pos/i15274.orig.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
enum Format[A]:
2+
case Str[Next](next: Format[Next]) extends Format[(String, Next)]
3+
case Num[Next](next: Format[Next]) extends Format[(Int, Next)]
4+
case Constant[Next](value: String, next: Format[Next]) extends Format[Next]
5+
case Done extends Format[Unit]
6+
7+
def printf[A](format: Format[A], params: A): Unit = (format, params) match
8+
case (Format.Done, ()) =>
9+
()
10+
11+
case (Format.Constant(value, next), params) =>
12+
println(value)
13+
printf(next, params)
14+
15+
case (Format.Str(next), (str, rest)) =>
16+
println(str)
17+
printf(next, rest)
18+
19+
case (Format.Num(next), (i, rest)) =>
20+
println(i)
21+
printf(next, rest)

tests/pos/i15274.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
enum Format[A]:
2+
case Str[Next](next: Format[Next]) extends Format[(String, Next)]
3+
4+
def printf[A](format: Format[A], params: A): Unit = (format, params) match
5+
case (Format.Str(next), (str, rest)) =>
6+
val s: String = str

0 commit comments

Comments
 (0)