Skip to content

Commit 67e692d

Browse files
authored
Merge pull request #15095 from dwijnand/infer-patmat-type-var
Heal pattern-bound type by gathering constraints
2 parents cb41597 + 414daeb commit 67e692d

File tree

3 files changed

+14
-3
lines changed

3 files changed

+14
-3
lines changed

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,14 +254,17 @@ 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+
// As a special case, when pattern and scrutinee types have the same type constructor,
259+
// we infer better bounds for pattern-bound abstract types.
260+
argP.typeSymbol.isPatternBound && patternTp.classSymbol == scrutineeTp.classSymbol
261+
then
259262
val TypeBounds(loS, hiS) = argS.bounds
260263
var res = true
261264
if variance < 1 then res &&= isSubType(loS, argP)
262265
if variance > -1 then res &&= isSubType(argP, hiS)
263266
res
264-
}
267+
else true
265268
}
266269
if !result then
267270
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)