Skip to content

Commit 172e957

Browse files
committed
Consider GADT upper bounds when upcasting the scrutinee type
1 parent 9d2d194 commit 172e957

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-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 => false
148+
}
149+
case _ => false
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.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)