Skip to content

Commit bf4f126

Browse files
committed
Heal pattern-bound type by gathering constraints
1 parent 1f4daea commit bf4f126

File tree

3 files changed

+13
-3
lines changed

3 files changed

+13
-3
lines changed

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,14 +254,16 @@ trait PatternTypeConstrainer { self: TypeComparer =>
254254
val result =
255255
tyconS.typeParams.lazyZip(argsS).lazyZip(argsP).forall { (param, argS, argP) =>
256256
val variance = param.paramVarianceSign
257-
if variance != 0 && !assumeInvariantRefinement then true
258-
else {
257+
if variance == 0 || assumeInvariantRefinement ||
258+
// heal the type if it's a (pattern-bound) type variable, provided we didn't upcast the pattern type:
259+
argP.typeSymbol.isPatternBound && patternTp.classSymbol == scrutineeTp.classSymbol
260+
then
259261
val TypeBounds(loS, hiS) = argS.bounds
260262
var res = true
261263
if variance < 1 then res &&= isSubType(loS, argP)
262264
if variance > -1 then res &&= isSubType(argP, hiS)
263265
res
264-
}
266+
else true
265267
}
266268
if !result then
267269
constraint = saved

tests/pos/i14739.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
abstract class Foo[+A]:
2+
def head: A
3+
def foo[T](xs: Foo[T]): T = xs match
4+
case xs: Foo[u] => xs.head: u

tests/pos/i14739.works.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
abstract class Foo[T]:
2+
def head: T
3+
def foo(xs: Foo[T]): T = xs match
4+
case xs: Foo[u] => xs.head: u

0 commit comments

Comments
 (0)