diff --git a/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala b/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala index ac7cbf6c36a6..119c3342fa81 100644 --- a/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala +++ b/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala @@ -138,13 +138,28 @@ trait PatternTypeConstrainer { self: TypeComparer => val andType = buildAndType(baseClasses) !andType.exists || constrainPatternType(pat, andType) case _ => - val upcasted: Type = scrut match { - case scrut: TypeProxy => scrut.superType - case _ => NoType + def tryGadtBounds = scrut match { + case scrut: TypeRef => + ctx.gadt.bounds(scrut.symbol) match { + case tb: TypeBounds => + val hi = tb.hi + constrainPatternType(pat, hi) + case null => true + } + case _ => true } - if (upcasted.exists) - tryConstrainSimplePatternType(pat, upcasted) || constrainUpcasted(upcasted) - else true + + def trySuperType = + val upcasted: Type = scrut match { + case scrut: TypeProxy => + scrut.superType + case _ => NoType + } + if (upcasted.exists) + tryConstrainSimplePatternType(pat, upcasted) || constrainUpcasted(upcasted) + else true + + tryGadtBounds && trySuperType } } diff --git a/tests/pos/i15274.orig.scala b/tests/pos/i15274.orig.scala new file mode 100644 index 000000000000..5d6887028f4f --- /dev/null +++ b/tests/pos/i15274.orig.scala @@ -0,0 +1,21 @@ +enum Format[A]: + case Str[Next](next: Format[Next]) extends Format[(String, Next)] + case Num[Next](next: Format[Next]) extends Format[(Int, Next)] + case Constant[Next](value: String, next: Format[Next]) extends Format[Next] + case Done extends Format[Unit] + +def printf[A](format: Format[A], params: A): Unit = (format, params) match + case (Format.Done, ()) => + () + + case (Format.Constant(value, next), params) => + println(value) + printf(next, params) + + case (Format.Str(next), (str, rest)) => + println(str) + printf(next, rest) + + case (Format.Num(next), (i, rest)) => + println(i) + printf(next, rest) diff --git a/tests/pos/i15274.scala b/tests/pos/i15274.scala new file mode 100644 index 000000000000..2862fd8f8cbc --- /dev/null +++ b/tests/pos/i15274.scala @@ -0,0 +1,6 @@ +enum Format[A]: + case Str[Next](next: Format[Next]) extends Format[(String, Next)] + +def printf[A](format: Format[A], params: A): Unit = (format, params) match + case (Format.Str(next), (str, rest)) => + val s: String = str